lstrcmp или byte to byte?

Тема в разделе "WASM.ASSEMBLER", создана пользователем shoom, 31 янв 2007.

  1. shoom

    shoom New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2006
    Сообщения:
    7
    Доброго времени суток.
    Собственно вопрос:
    Какой способ сравнения наиболее быстр в приложениях(напр. брутфорсы),где скорость критична?
     
  2. nitrotoluol

    nitrotoluol New Member

    Публикаций:
    0
    Регистрация:
    5 сен 2006
    Сообщения:
    848
    repz cmpsb

    поскольку в апи юзается тоже самое, но добавляется лишний кэл, рэт и запушивание адресов.

    А вообще вопрос элементарный. Мог бы и сам догнать.
     
  3. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Ни то, ни другое не верно. Хоть kernel32.lstrcmp и тормоз, но ntdll.strcmp всё же пошустрее будет, т.к. cmps да ещё и с rep - далеко не быстрые операции.
     
  4. W4FhLF

    W4FhLF New Member

    Публикаций:
    0
    Регистрация:
    3 дек 2006
    Сообщения:
    1.050
    Код (Text):
    1. ;================================================================================
    2. ;   Процедура сравнения строк с учётом регистра
    3. ;   Возвращаемое значение: если строки совпадают, eax==0;
    4. ;                          если str1<str2, eax < 0;
    5. ;                          если str1>str2, eax > 0.
    6. ;                          модуль eax==номер несовпавших символов от начала строки
    7.  
    8. align 16
    9. cr_strcmp   proc str1:DWORD, str2:DWORD
    10.    
    11.     push    esi
    12.     push    edi
    13.     push    ebx
    14.  
    15.     mov     esi,str1                    ;esi    => string 1
    16.     mov     edi,str2                    ;edi    => string 2
    17.     mov     ebx,-4
    18.     jmp     @F
    19. align 16
    20. _cmp:
    21.     cmp     edx,[edi+ebx]           ;если не конец, сравниваем с сохраненным двордом
    22.     jne     _byte
    23.  @@:
    24.     add     ebx,4
    25.     mov     eax,[esi+ebx]           ;дворд из первой строки
    26.     lea     ecx,[eax-01010101h]     ;вычитаем из каждого байта 1, если был ноль, то будет FFh
    27.     not     eax                     ;инвертируем, если был ноль будет FFh
    28.     and     ecx,eax                 ;and : если был ноль, на его месте будет FFh
    29.     and     ecx,80808080h           ;на месте исходного нулевого байта будет 80h, в остальных - ноль
    30.     mov     edx,[esi+ebx]           ;загружаем для сравнения
    31.     jz      _cmp                    ;если не ноль (один из байтов = 80h) - конец строки
    32.    
    33. _byte:    
    34.     mov     ecx,[edi+ebx]
    35.     lea     eax,[ebx+1]
    36.     cmp     dl,cl
    37.     jne     mismatch                ;string 1 != string 2
    38.     test    dl,dl
    39.     jz      _equ                    ;string 1 = string 2
    40.     inc     eax
    41.     cmp     dh,ch
    42.     jne     mismatch
    43.     test    dh,dh
    44.     jz      _equ
    45.     inc     eax
    46.     shr     edx,16
    47.     shr     ecx,16
    48.     cmp     dl,cl
    49.     jne     mismatch
    50.     test    dl,dl
    51.     jz      _equ
    52.     inc     eax
    53.     cmp     dh,ch
    54.     jne     mismatch
    55.     jmp     _equ
    56. align 16    
    57. mismatch:
    58.     jg      @ret
    59.     neg     eax
    60.     jmp     @ret
    61. _equ:
    62.     xor     eax,eax
    63. @ret:
    64.     pop     ebx
    65.     pop     edi
    66.     pop     esi
    67.     ret
    68.  
    69. cr_strcmp endp
     
  5. shoom

    shoom New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2006
    Сообщения:
    7
    Я так и думал. byte to byte - быстрее некуда.Только вот как еще можно это оптимизировать(в плане минимизации операций процессором)?
    W4FhLF,спасибо за сорц!
     
  6. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    shoom
    У Фога посмотри, он как раз это рассматривал, принцип тот же, что и у W4FhLF.
     
  7. slackhead

    slackhead New Member

    Публикаций:
    0
    Регистрация:
    29 янв 2007
    Сообщения:
    66
    Простите за ламерский вопрос, скопировал сорец Wolf'а а он ругается на строку align 16:
    Код (Text):
    1. invalid combination with segment alignment : 16
     
  8. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    slackhead
    Выравнивание внутри секции по понятным причинам не может быть больше выравнивания самой секции. Нужно либо уменьшить значение операнда align (до 4), либо вручную переписать заголовок секции кода (вместо .CODE) и задать там выравнивание начала секции >= 16. См. тут:
    http://www.wasm.ru/forum/viewtopic.php?id=16841
     
  9. nitrotoluol

    nitrotoluol New Member

    Публикаций:
    0
    Регистрация:
    5 сен 2006
    Сообщения:
    848
    IceStudent
    Для меня новость. :))) Так ведь разве размер не влияет на скорость..? По моему куда еще меньше....
    И по моему, я явно чего-то не понимаю... :)
     
  10. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    nitrotoluol
    Время выполнения прямо пропорционально размеру кода только на RISC-процессорах. :)
    latency у "rep cmpsb" если верить Фогу:
    на Core 2: 2+7n - 22+5n
    на P4: ~50+8n
    на P4E: ~81+8n
    на AMD64, правда, если ему верить всего 2n, но во-первых, что-то мне не вериться (надо будет проверить, однако), а во-вторых можно быстрее.
     
  11. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Ustus
    А если верить мануалу AMD64 Optim, то rep cmps у них самая медленная (по ср. с другими rep) и выполняется 16+(10/3)*n тактов
     
  12. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    leo
    А я вчера проверил :) действительно repe cmps выполняется порядка 2*n тиков.
    А вот на P4E у меня получилось ~9*n :dntknw: Правда мерял уже в полуспящем состоянии. Это есть очень плёхо - даже замена на тупорылое
    Код (Text):
    1. ll:
    2.   mov   al, [esi+ecx]
    3.   cmp   al, [edi+ecx]
    4.   jne    ne
    5.   add   ecx, 1
    6.   jnz   ll
    дает уже 7*n (на A64, правда, аж 3*n :) )