Что эффективнее

Discussion in 'WASM.BEGINNERS' started by ADim, Jun 5, 2007.

  1. ADim

    ADim New Member

    Blog Posts:
    0
    Если заранее известно, что в данной точке кода EAX == 0, и мне нужна единица в ECX, что будет эффективнее:
    Так:
    xor ecx,ecx
    dec ecx
    Или:
    lea ecx,[eax-1]
    Длина - 3 байта в любом случае, но в первом инструкций две, причем вторая зависит от резутатов первой. Это имеет значение? Или же в любом случае 1 такт?
    Просто mov ecx,1 - 5 байт.
     
  2. Vov4ick

    Vov4ick Владимир

    Blog Posts:
    0
    А нужна скорость или размер? Если скорость - mov ecx,1 ,а если размер - решай сам. (только не dec, а inc)
     
  3. leo

    leo Active Member

    Blog Posts:
    0
    Во-первых, есть еще один 3-х байтный вариант
    or ecx,-1 ;-1 = sign-extended byte

    Во-вторых, судить по одной-двум инструкциям, что в итоге будет эффективней не вполне корректно, т.к. проц работает с потоком команд и может выполнять за такт несколько операций, изменяя их порядок на глубине до 8-16 и более. Не считая mov, все варианты имеют зависимости от предыдущего значения (eax или ecx), но для lea и or эта зависимость определяется неизвестными предыдущими командами, а в варианте с xor она присутсвует явно. Причем нужно иметь в виду, что в современных процессорах команды xor\sub регистра с самим собой имеют особый смысл операций очистки регистра и считаются независящими от его предыдущего значения и поэтому (также как и NOP) могут выполняться вне очереди в любой подходящий момент (в т.ч параллельно с другими операциями). Поэтому в отрыве от окружающего кода говорить о том, что в итоге будет быстрее - не корректно. Если для тебя один такт и пару байт критичны, то нужно рассматривать и оптимизировать весь кусок, если же нет - то используй любой вариант по вкусу

    PS: Кстати inc\dec не очень хорошие инструкции, т.к. они вносят зависимость по флагу CF, и к тому же в x86-64, за которыми как ни крути - будущее, однобайтные inc\dec "ликвидированы" и оставлены только двухбайтные
     
  4. asmfan

    asmfan New Member

    Blog Posts:
    0
    Никаким макаром единица тута не получается.
     
  5. wasm_test

    wasm_test wasm test user

    Blog Posts:
    0
    видно, ему нужна -1 в ecx
     
  6. asmfan

    asmfan New Member

    Blog Posts:
    0
    Great
    ) а последняя строка аффтора:
    Вот и гадай что да как и почему.)
     
  7. crypto

    crypto Active Member

    Blog Posts:
    0
    ADim
    Вот в этом фрагментике программы, скомпилированной Мелкософтовским компилятором, информация о том, что eax=0, не используется при задании ecx=-1
    Так что воспользуйся советом leo.
     
  8. axe_roma

    axe_roma New Member

    Blog Posts:
    0
    Вот я тоже немогу понять толи ему 1 толи -1 нужен. Ты напиши конкретно
     
  9. Mikl_

    Mikl_ New Member

    Blog Posts:
    0
    ADim
    можно и так xchg eax,ecx/inc ecx (2 байта)
     
  10. leo

    leo Active Member

    Blog Posts:
    0
    Mikl__
    Меняем байты на такты ? ;)
     
  11. ADim

    ADim New Member

    Blog Posts:
    0
    Great, asmfan
    Я ошибся в описании! Нужна -1 ("минус единица"). Соответственно, mov ecx, 0ffffffffh ; -1
    Mikl__
    К сожалению, при этом теряется 0 в eax, придется добавить xor eax,eax. + 2 байта.
    leo
    Ваш вариан or ecx,-1 со знаковым расширением очень удачен, спасибо.
    После операций очистки регистров, т.е. установки регистров в определенное значение 0, зависимость сохраняется? Т.е. после XOR ECX,ECX до следующего изменения ECX не допускается внеочередного исполнения команд с участием ECX (без его изменения)?
    Насколько вероятно в процессорах, начиная с P6, не одновременное исполнение xor ecx,ecx / dec ecx ???
    А интересовало меня, можно ли в три байта уложиться в один такт, если эти три байта - не одна инструкция, точнее, насколько вероятно, что поток команд так попадет в устройства процессора, что исполнение их займет один такт. Предыдущих команд, наподобие fsin, полностью маскирующих время след. инструкций нет или, еще лучше, может не быть.
    --
    --
    Не могли бы вкратце пояснить, будет ли разница в обнулении регистра (общего) SUB или XOR?
     
  12. leo

    leo Active Member

    Blog Posts:
    0
    ADim
    Какие то запутанные вопросы задаешь ;)
    1) Разницы в использовании xor или sub для обнуления нет (если быть точным, то только в P4 м.б. тонкая разница, т.к. в P4 логический блок один, а add\sub - два)
    2) Операции xor и dec не могут выполниться одновременно, т.к. dec зависит от xor, поэтому за один такт они вместе выполниться никак не могут
    3) Но xor, будучи независимой операцией, может выполниться раньше, параллельно с другими операциями (в том числе и одновременно и даже раньше предыдущих операций, изменяющих этот же регистр !). Подобие fsin тут никчему, т.к. во-первых, современные процы могут выполнять одновременно 2-3 целочисленных операции плюс 1-3 операции вычисления адреса для mov, во-вторых, во время исполнения операциий mov c памятью, mul\imul и т.п. может быть выполнено множество других простых операций.
    Примеры
    Code (Text):
    1. ;Код 1А
    2. add ecx,4     ;1й такт
    3. mov [ebx],ecx ;2й такт
    4. or ecx,-1     ;2й такт, т.к. зависит от add ecx,4
    5.  
    6. ;Код 1Б
    7. add ecx,4     ;1й такт
    8. mov [ebx],ecx ;2й такт
    9. xor ecx,ecx   ;1й такт, если попадает в одну тройку с add ecx
    10. dec ecx       ;2й такт, т.к. зависит от xor
    11.  
    12. ;Код 2А
    13. add ecx,[ebx]     ;1-4й такты (3 на загрузку, 1 на add)
    14. mul ecx           ;5-?й такты (3\4-5\10\14 в завис.от проца)
    15. or ecx,-1         ;5й такт, т.к. зависит от add ecx,[ebx]
    16.  
    17. ;Код 2Б
    18. add ecx,[ebx]     ;1-4й такты
    19. mul ecx           ;5-?й такты
    20. xor ecx,ecx       ;1й или 2й такт, т.к. не зависит от ecx
    21. dec ecx           ;2й или 3й такт
    Вывод: нельзя рассматривать две инструкции в отрыве от предыдущего кода - в зависимости от откружения м.б. либо один вариант быстрее, либо другой, либо без разницы

    PS: Чтобы не было лишних вопросов: в примере 2Б xor может выполниться раньше изменения ecx и mul за счет переименования регистров в процессоре (операциям add и mul назначается внутренний регистр ecx==R, а операциям xor и dec ecx==R[i+1])
     
  13. Mikl_

    Mikl_ New Member

    Blog Posts:
    0
    ADim
    команда MOV не имеет знакового расширения в отличее от логических команд (OR,XOR,AND), но если в одном из регистров у вас 0 (я использую EBX=0), то
    Code (Text):
    1. B80D000000   mov eax,0Dh (5 байт)
    2. 8D430D         lea eax,[ebx+0Dh](3 байта)
    3. B8FFFFFFFF   mov eax,-1(5 байт)
    4. 8D43FF         lea eax,[ebx-1](3 байта)
    а про быстродействие пусть leo скажет ;)
     
  14. leo

    leo Active Member

    Blog Posts:
    0
    Mikl__
    А у ADim то же самое, только EAX=0 ;)
    А насчет быстродействия - на атлонах lea r,[r+i] выполняется 2 такта, на остальных камнях 1 такт. Если регистр сброшен "давно и надолго", то зависимости можно не учитывать
     
  15. ADim

    ADim New Member

    Blog Posts:
    0
    Большое спасибо, многое стало ясно :) Про разницу sub/xor спрашивал, т.к. в руководстве по оптимизации для K8 указана XOR, а для P4 - XOR или SUB. Ремарок там нет.