align

Тема в разделе "WASM.ASSEMBLER", создана пользователем cresta, 19 июн 2005.

  1. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    О положительном влиянии выравненности адресов данных и кода много говорилось, но что-то есть непонятные моменты :dntknw: То, что касается данных, то align всегда улучшает скорость доступа к данным. А вот что касается кода, тут практически всегда (за редким исключением) align снижает скорость. Пример:


    Код (Text):
    1. align 16
    2. ;=====================================================================  ===========
    3. cr_multicat proc C str_count:DWORD,lpBuffer:DWORD,params:VARARG
    4.     option prologue : none
    5.     option epilogue : none
    6.    
    7.     push esi
    8.     push edi
    9.     push ebx
    10.     push ebp
    11.  
    12.     mov     edi,[esp+24]          
    13.     lea     edx,[edi+3]
    14.   @@:    
    15.     mov     eax,[edi]
    16.     add     edi,4
    17.     lea     ecx,[eax-01010101h]
    18.     not     eax
    19.     and     ecx,eax
    20.     and     ecx,80808080h
    21.     jz      @B
    22.     test    ecx,00008080h
    23.     jnz     @F
    24.     shr     ecx,16
    25.     add     edi,2
    26.   @@:
    27.     shl     cl,1
    28.     sbb     edi,edx
    29.     add     edi,[esp+24]
    30.     xor     ecx,ecx
    31.    
    32. align 4  
    33. next_string:
    34.     lea     edx,[esp+28]
    35.     mov     esi,[edx+ecx*4]
    36.     lea     edx,[esi+3]
    37.     mov     ebp,edi
    38.     jmp     @F
    39. ;align 4                            
    40. copy:
    41.           mov     eax,[esi-4]
    42.           mov     [edi-4],eax
    43.   @@:
    44.     mov     eax,[esi]
    45.     add     esi,4
    46.     add     edi,4
    47.     lea     ebx,[eax-01010101h]
    48.     not     eax
    49.     and     ebx,eax
    50.     and     ebx,80808080h
    51.     jz      copy
    52.  
    53.     mov     al,[esi-4]
    54.     mov     [edi-4],al
    55.     test    al,al
    56.     jz      @F
    57.     mov     al,[esi-3]
    58.     mov     [edi-3],al
    59.     test    al,al
    60.     jz      @F
    61.     mov     al,[esi-2]
    62.     mov     [edi-2],al
    63.     test    al,al
    64.     jz      @F
    65.     mov     al,[esi-1]
    66.     mov     [edi-1],al
    67.     test    al,al
    68.     jz      @F
    69.     @@:
    70.     test    ebx,00008080h
    71.     jnz     @F
    72.     shr     ebx,16
    73.     add     esi,2
    74.   @@:
    75.     shl     bl,1
    76.     sbb     esi,edx
    77.     mov     edi,ebp
    78.     add     edi,esi
    79.     inc     ecx
    80.     cmp     ecx,[esp+20]
    81.     jne     next_string
    82.     sub     edi,[esp+24]
    83.     mov     eax,edi
    84.     pop ebp
    85.     pop ebx
    86.     pop edi
    87.     pop esi
    88.     retn
    89.     option prologue : prologuedef
    90.     option epilogue : epiloguedef
    91.    
    92. cr_multicat endp




    Первый align 4 (перед циклом по метке next_string) ухудшает время выполнения кода на 1 тик. В этом месте компилятор вставляет mov edi,edi. Получается, что align не даёт ничего, а за счет mov edi,edi происходит ухудшение на 1 тик.



    Второй align, закомментированный (перед меткой copy) ухудшает время на 9 тиков. Там также вместо align вставляется mov edi,edi. Причём этот mov edi,edi не выполняется никогда: перед ним стоит jmp. Почему с адресом метки цикла, кратным 4, цикл работает медленней, при том же кол-ве выполняемых инструкций???
     
  2. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    align 4 бессмысленен для кода, только размер увеличивает! Хотя даже Intel C++ его везде лепит :/

    Нужно делать align 16, да и то, только когда это действительно необходимо.
     
  3. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Я бы уточнил: "бездумный - на всякий случай" align 4 бессмысленен для кода, т.к. не только увеличивает размер, но и требует времени для исполнения NOP-инструкций (или их заменителей), а еще может привести и к неожиданным потерям (впрочем как и align 16). Поэтому align 4 или 8 можно использовать только при мелочной ручной "супер"-оптимизации по скорости, когда экспериментально видно, что они позволяют что-то заметно сэкономить. А хитрости эти связаны с особенностями фетча и декодирования инструкций выравненными блоками по 16 или 32 байта, т.е. при переходе на метку адрес блока декодирования = адресу метки округленному вниз на 16 или 32. Поэтому изменяя адрес метки на 4 мы фактически просто уменьшаем число инструкций в текущем блоке и можем либо нарваться на неприятности или наоборот устранить. В частности, PIII "не нравится" когда команда условного перехода или другая "важная" команда разбивается границей блока декодирования или когда все тело цикла лежит в одном блоке, а jcc оказывается в начале следующего. Поэтому иногда align 4 (или 8 или вообще без align) может работать чуть быстрее чем align 16. Но без проверки ес-но на это расчитывать нельзя и поэтому совать где-попало align 4 конечно бессмысленно.
     
  4. zzzyab

    zzzyab New Member

    Публикаций:
    0
    Регистрация:
    13 май 2004
    Сообщения:
    115
    А есть смысл ставить алигн на начало продседуры или на табличное jmp:
    Код (Text):
    1.  
    2. align 4
    3. proc1:
    4. ..
    5. ...
    6. ...
    7. ret
    8. align 4
    9. proc2:
    10. ..
    11. ..
    12. ..
    13. ret
    14. ....
    15. jmp dword ptr [table+eax]
    16. l001:
    17. ..
    18. l002:
    19. ..
    20. l003:
    21. ..
    22. l004:
    23. ..
    24. align 4
    25. table:
    26. dd l001,l002,l003,l004
    27.