Оптимизация вплоть до такта

Тема в разделе "WASM.A&O", создана пользователем BUGOR, 9 окт 2005.

  1. BUGOR

    BUGOR New Member

    Публикаций:
    0
    Регистрация:
    14 авг 2005
    Сообщения:
    44
    Здраствуйте уважаемые, хотел спросить у вас совета:



    Пишу программу, в которой скорость выполнения инструкций в цикле играет ключевую роль, каждый такт идёт в счёт, проситал статьи по оптимизации у вас, но окончательного ответа не нашёл:



    1. Как быстрее измерить длину строки?



    2. Как быстрее очистить некую область памяти(размер области известен)



    3. Как быстрее переместить данные из одной области в памяти в другую?(размер известен)



    4. Как быстрее сравнить две строки?(размер известен)



    Если подкрепите свой ответ примером, буду очень признателен!

    Заранее благодарен.
     
  2. CrazyFun

    CrazyFun New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2005
    Сообщения:
    129
    думаю строковые каоманды помогут.. хотя мб есть и более быстрые методы..
     
  3. bogrus

    bogrus Active Member

    Публикаций:
    0
    Регистрация:
    24 окт 2003
    Сообщения:
    1.338
    Адрес:
    ukraine
    BUGOR Ищи по форуму (кажется в этом разделе), были коды на все 4 ф-ции, у тебя известен размер - можно ещё под отдельный камень пооптимизировать



    Тем уже нет, искать надо в оффлайн или гугле, вот strlen для не очень маленьких строк
    Код (Text):
    1. ;======================================
    2. strlenA:    mov     eax,[esp+4]
    3. align 16
    4. @@:         mov     ecx,dword[eax]
    5.             and     ecx,0x7F7F7F7F
    6.             add     ecx,0x7F7F7F7F
    7.             or      ecx,dword[eax]
    8.             add     eax,4
    9.             or      ecx,0x7F7F7F7F
    10.             add     ecx,1
    11.             jz      @b
    12.             neg     ecx
    13.             bsf     ecx,ecx
    14.             add     ecx,1
    15.             shr     ecx,3
    16.             sub     ecx,5
    17.             add     eax,ecx
    18.             sub     eax,[esp+4]
    19.             ret     4
    20. ;======================================
    Код (Text):
    1. =========================================
    2. Длина строки/такты | lstrlen  | strlenA |
    3. =========================================
    4.   10           |      118 |       30
    5.  100           |      475 |      140
    6. 1000           |     4047 |     1070(выровн4)/1510(невыровн)
    7. =========================================
     
  4. BUGOR

    BUGOR New Member

    Публикаций:
    0
    Регистрация:
    14 авг 2005
    Сообщения:
    44
    bogrus

    Огромное спасибо, попробую!



    А насчёт 3 и 4 не мог бы ты мне помочь? Неужели никто не может помочь?
     
  5. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    В аттаче 3 функции, оптимизированные примерно под такую же задачу: многократный вызов в цикле.





    [​IMG] 1482259362__strfuncs.asm
     
  6. SDragon

    SDragon New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2005
    Сообщения:
    133
    Адрес:
    Siberia
    Быстрее использовать строки в стиле Pascal. Тогда 1 сводится к чтению длины из переменной, 4 также ускоряется (сначала можно проверить, равна ли длина строк, а затем - равны ли сами строки).



    Вообще, при операциях с буферами и строками удобнее хранить длину буфера, чем работать с null terminated-строками. Многие API-функции возвращают длину строки, записанной в буфер, поэтому никаких дополнительных расходов на вызов strlen не требуется.
     
  7. koderr

    koderr New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2006
    Сообщения:
    205
    Вот strcmp из ntdll.dll, работает довольно быстро (намного быстрее lstrlenA из kernel32.dll):
    Код (Text):
    1. mystrcmp macro
    2. ;compares two strings:
    3. ; ecx -> str1
    4. ; edx -> str2
    5.  
    6.     test    edx, 3
    7.     jnz short @not_dword_aligned
    8.  
    9. @go_on:
    10.     mov eax, [edx]
    11.     cmp al, [ecx]
    12.     jnz short @not_equal
    13.     test    al, al
    14.     jz  short @null_reached
    15.     cmp ah, [ecx+1]
    16.     jnz short @not_equal
    17.     test    ah, ah
    18.     jz  short @null_reached
    19.     shr eax, 10h
    20.     cmp al, [ecx+2]
    21.     jnz short @not_equal
    22.     test    al, al
    23.     jz  short @null_reached
    24.     cmp ah, [ecx+3]
    25.     jnz short @not_equal
    26.     add ecx, 4
    27.     add edx, 4
    28.     test    ah, ah
    29.     jnz short @go_on
    30.    
    31.     align 4
    32. @null_reached:
    33.     xor eax, eax
    34.     jmp short @end
    35.  
    36.     align 4
    37. @not_equal:
    38.     sbb eax, eax
    39.     add eax, eax
    40.     add eax, 1
    41.     jmp short @end
    42.  
    43.     align 4
    44. @not_dword_aligned:
    45.     test    edx, 1
    46.     jz  short @word_aligned
    47.     mov al, [edx]
    48.     add edx, 1
    49.     cmp al, [ecx]
    50.     jnz short @not_equal
    51.     add ecx, 1
    52.     test    al, al
    53.     jz  short @null_reached
    54.     test    edx, 2
    55.     jz  short @go_on
    56.  
    57. @word_aligned:
    58.     mov ax, [edx]
    59.     add edx, 2
    60.     cmp al, [ecx]
    61.     jnz short @not_equal
    62.     test    al, al
    63.     jz  short @null_reached
    64.     cmp ah, [ecx+1]
    65.     jnz short @not_equal
    66.     test    ah, ah
    67.     jz  short @null_reached
    68.     add ecx, 2
    69.     jmp short @go_on
    70. @end:
    Я думаю переписать код между @go_on и @null_reached так: читаем по дворду с каждой строки, вычитаем одно из другого, проверяем на конец строки по Агнеру Фогу... Так быстрее получится или нет? Как считаете?
     
  8. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Может, lstrcmpA? :)
     
  9. koderr

    koderr New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2006
    Сообщения:
    205
    Да-да :) Очепятка, сорри.

    Кстати, разница в скорости очень существенная: если программа с ntdll.strcmp обрабатывает файл за 6 секунд, то с использованием kernel32.lstrcmpA она обрабатывает его аж за 18 секунд!