Доброго времени суток. Собственно вопрос: Какой способ сравнения наиболее быстр в приложениях(напр. брутфорсы),где скорость критична?
repz cmpsb поскольку в апи юзается тоже самое, но добавляется лишний кэл, рэт и запушивание адресов. А вообще вопрос элементарный. Мог бы и сам догнать.
Ни то, ни другое не верно. Хоть kernel32.lstrcmp и тормоз, но ntdll.strcmp всё же пошустрее будет, т.к. cmps да ещё и с rep - далеко не быстрые операции.
Код (Text): ;================================================================================ ; Процедура сравнения строк с учётом регистра ; Возвращаемое значение: если строки совпадают, eax==0; ; если str1<str2, eax < 0; ; если str1>str2, eax > 0. ; модуль eax==номер несовпавших символов от начала строки align 16 cr_strcmp proc str1:DWORD, str2:DWORD push esi push edi push ebx mov esi,str1 ;esi => string 1 mov edi,str2 ;edi => string 2 mov ebx,-4 jmp @F align 16 _cmp: cmp edx,[edi+ebx] ;если не конец, сравниваем с сохраненным двордом jne _byte @@: add ebx,4 mov eax,[esi+ebx] ;дворд из первой строки lea ecx,[eax-01010101h] ;вычитаем из каждого байта 1, если был ноль, то будет FFh not eax ;инвертируем, если был ноль будет FFh and ecx,eax ;and : если был ноль, на его месте будет FFh and ecx,80808080h ;на месте исходного нулевого байта будет 80h, в остальных - ноль mov edx,[esi+ebx] ;загружаем для сравнения jz _cmp ;если не ноль (один из байтов = 80h) - конец строки _byte: mov ecx,[edi+ebx] lea eax,[ebx+1] cmp dl,cl jne mismatch ;string 1 != string 2 test dl,dl jz _equ ;string 1 = string 2 inc eax cmp dh,ch jne mismatch test dh,dh jz _equ inc eax shr edx,16 shr ecx,16 cmp dl,cl jne mismatch test dl,dl jz _equ inc eax cmp dh,ch jne mismatch jmp _equ align 16 mismatch: jg @ret neg eax jmp @ret _equ: xor eax,eax @ret: pop ebx pop edi pop esi ret cr_strcmp endp
Я так и думал. byte to byte - быстрее некуда.Только вот как еще можно это оптимизировать(в плане минимизации операций процессором)? W4FhLF,спасибо за сорц!
Простите за ламерский вопрос, скопировал сорец Wolf'а а он ругается на строку align 16: Код (Text): invalid combination with segment alignment : 16
slackhead Выравнивание внутри секции по понятным причинам не может быть больше выравнивания самой секции. Нужно либо уменьшить значение операнда align (до 4), либо вручную переписать заголовок секции кода (вместо .CODE) и задать там выравнивание начала секции >= 16. См. тут: http://www.wasm.ru/forum/viewtopic.php?id=16841
IceStudent Для меня новость. )) Так ведь разве размер не влияет на скорость..? По моему куда еще меньше.... И по моему, я явно чего-то не понимаю...
nitrotoluol Время выполнения прямо пропорционально размеру кода только на RISC-процессорах. latency у "rep cmpsb" если верить Фогу: на Core 2: 2+7n - 22+5n на P4: ~50+8n на P4E: ~81+8n на AMD64, правда, если ему верить всего 2n, но во-первых, что-то мне не вериться (надо будет проверить, однако), а во-вторых можно быстрее.
Ustus А если верить мануалу AMD64 Optim, то rep cmps у них самая медленная (по ср. с другими rep) и выполняется 16+(10/3)*n тактов
leo А я вчера проверил действительно repe cmps выполняется порядка 2*n тиков. А вот на P4E у меня получилось ~9*n Правда мерял уже в полуспящем состоянии. Это есть очень плёхо - даже замена на тупорылое Код (Text): ll: mov al, [esi+ecx] cmp al, [edi+ecx] jne ne add ecx, 1 jnz ll дает уже 7*n (на A64, правда, аж 3*n )