О положительном влиянии выравненности адресов данных и кода много говорилось, но что-то есть непонятные моменты То, что касается данных, то align всегда улучшает скорость доступа к данным. А вот что касается кода, тут практически всегда (за редким исключением) align снижает скорость. Пример: Код (Text): align 16 ;===================================================================== =========== cr_multicat proc C str_count:DWORD,lpBuffer:DWORD,params:VARARG option prologue : none option epilogue : none push esi push edi push ebx push ebp mov edi,[esp+24] lea edx,[edi+3] @@: mov eax,[edi] add edi,4 lea ecx,[eax-01010101h] not eax and ecx,eax and ecx,80808080h jz @B test ecx,00008080h jnz @F shr ecx,16 add edi,2 @@: shl cl,1 sbb edi,edx add edi,[esp+24] xor ecx,ecx align 4 next_string: lea edx,[esp+28] mov esi,[edx+ecx*4] lea edx,[esi+3] mov ebp,edi jmp @F ;align 4 copy: mov eax,[esi-4] mov [edi-4],eax @@: mov eax,[esi] add esi,4 add edi,4 lea ebx,[eax-01010101h] not eax and ebx,eax and ebx,80808080h jz copy mov al,[esi-4] mov [edi-4],al test al,al jz @F mov al,[esi-3] mov [edi-3],al test al,al jz @F mov al,[esi-2] mov [edi-2],al test al,al jz @F mov al,[esi-1] mov [edi-1],al test al,al jz @F @@: test ebx,00008080h jnz @F shr ebx,16 add esi,2 @@: shl bl,1 sbb esi,edx mov edi,ebp add edi,esi inc ecx cmp ecx,[esp+20] jne next_string sub edi,[esp+24] mov eax,edi pop ebp pop ebx pop edi pop esi retn option prologue : prologuedef option epilogue : epiloguedef 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, цикл работает медленней, при том же кол-ве выполняемых инструкций???
align 4 бессмысленен для кода, только размер увеличивает! Хотя даже Intel C++ его везде лепит :/ Нужно делать align 16, да и то, только когда это действительно необходимо.
Я бы уточнил: "бездумный - на всякий случай" align 4 бессмысленен для кода, т.к. не только увеличивает размер, но и требует времени для исполнения NOP-инструкций (или их заменителей), а еще может привести и к неожиданным потерям (впрочем как и align 16). Поэтому align 4 или 8 можно использовать только при мелочной ручной "супер"-оптимизации по скорости, когда экспериментально видно, что они позволяют что-то заметно сэкономить. А хитрости эти связаны с особенностями фетча и декодирования инструкций выравненными блоками по 16 или 32 байта, т.е. при переходе на метку адрес блока декодирования = адресу метки округленному вниз на 16 или 32. Поэтому изменяя адрес метки на 4 мы фактически просто уменьшаем число инструкций в текущем блоке и можем либо нарваться на неприятности или наоборот устранить. В частности, PIII "не нравится" когда команда условного перехода или другая "важная" команда разбивается границей блока декодирования или когда все тело цикла лежит в одном блоке, а jcc оказывается в начале следующего. Поэтому иногда align 4 (или 8 или вообще без align) может работать чуть быстрее чем align 16. Но без проверки ес-но на это расчитывать нельзя и поэтому совать где-попало align 4 конечно бессмысленно.
А есть смысл ставить алигн на начало продседуры или на табличное jmp: Код (Text): align 4 proc1: .. ... ... ret align 4 proc2: .. .. .. ret .... jmp dword ptr [table+eax] l001: .. l002: .. l003: .. l004: .. align 4 table: dd l001,l002,l003,l004