в каких местах MMX даёт прирост производительности

Тема в разделе "WASM.ASSEMBLER", создана пользователем rpy3uH, 18 фев 2012.

  1. rpy3uH

    rpy3uH New Member

    Публикаций:
    0
    Регистрация:
    14 сен 2006
    Сообщения:
    503
    есть две функции которые принимают на вход два массива и работают над ними. написал две функции которые делают одно и тоже, одна обычная другая через MMX
    Код (Text):
    1. ;       ESI - первый буфер
    2. ;       EDI - второй буфер
    3. ;       ECX - размер буфера
    4. CalcVals_nonMMX:
    5.         shr ecx, 1
    6.  
    7.        .loop:
    8.         mov ax, [esi]
    9.         mov dx, [edi]
    10.         add ax, dx
    11.         shl ax, 1
    12.         shr dx, 1
    13.         sub ax, dx
    14.         mov [esi], dx
    15.         mov [edi], ax
    16.         add esi, 2
    17.         add edi, 2
    18.         dec ecx
    19.         jnz .loop
    20.  
    21.         ret
    22.  
    23. CalcVals_MMX:
    24.         shr ecx, 3
    25.  
    26.        .loop:
    27.         movq mm0, [esi]
    28.         movq mm1, [edi]
    29.         paddw mm0, mm1
    30.         psllw mm0, 1
    31.         psrlw mm1, 1
    32.         psubw mm0, mm1
    33.         movq [esi], mm1
    34.         movq [edi], mm0
    35.  
    36.         add esi, 8
    37.         add edi, 8
    38.         dec ecx
    39.         jnz .loop
    40.  
    41.         ret
    cсобственно тестирование
    Код (Text):
    1. BufferSize dd  16*1024*1024  
    2.  
    3.         call [GetTickCount]
    4.         push eax
    5.  
    6.         rdtsc
    7.         push edx
    8.         push eax
    9.  
    10.         mov ebx, 100
    11.        @@:
    12.         mov esi, [nonMMX_Buffer1]
    13.         mov edi, [nonMMX_Buffer2]
    14.         mov ecx, [BufferSize]
    15.         call CalcVals_nonMMX
    16.         dec ebx
    17.         jnz @b
    18.  
    19.         rdtsc
    20.         pop ecx
    21.         pop ebx
    22.         sub eax, ecx
    23.         sbb edx, ebx
    24.  
    25.         call [GetTickCount]
    26.         pop ecx
    27.         sub eax, ecx
    28.  
    29.         call [GetTickCount]
    30.         push eax
    31.  
    32.         rdtsc
    33.         push edx
    34.         push eax
    35.  
    36.         mov ebx, 100
    37.        @@:
    38.         mov esi, [MMX_Buffer1]
    39.         mov edi, [MMX_Buffer2]
    40.         mov ecx, [BufferSize]
    41.         call CalcVals_MMX
    42.         dec ebx
    43.         jnz @b
    44.  
    45.         rdtsc
    46.         pop ecx
    47.         pop ebx
    48.         sub eax, ecx
    49.         sbb edx, ebx
    50.  
    51.         call [GetTickCount]
    52.         pop ecx
    53.         sub eax, ecx
    результаты не очень сильно различаются. замер через rdtsc даёт мизерное преимущество MMX. GetTickCount даёт одинаковое время.

    где подвох?
     
  2. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    Подвох в размере массива.
    Оба алгоритма работают работают быстро, но вот при таком большом размере кэш не работает и основная задержка идёт на чтение и запись. Вот будь алгоритм по сложнее или массив по корочи к примеру уменьши его в 16 раз сразу увидишь 4-х кратное увеличение скорости.
     
  3. rpy3uH

    rpy3uH New Member

    Публикаций:
    0
    Регистрация:
    14 сен 2006
    Сообщения:
    503
    пробовал 64К, 1М и 4М, тоже самое


    спасибо. попробовал миллион раз с размером 4КБ, MMX быстрее примерно в 3.8 раза
     
  4. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    rpy3uH
    А процессор у тебя какой?
     
  5. rpy3uH

    rpy3uH New Member

    Публикаций:
    0
    Регистрация:
    14 сен 2006
    Сообщения:
    503
    отбой. всё нормально. тупанул с кэшем

    проц ноутбучный Pentium D 1.86 ГГц
     
  6. rpy3uH

    rpy3uH New Member

    Публикаций:
    0
    Регистрация:
    14 сен 2006
    Сообщения:
    503
    заметил что чем сложнее алгоритм тем больше прирост даёт MMX

    например вот два алгоритма. MMX даёт прирост в более чем 10 раз.
    но есть косяк. в 5-4% результаты вычислений различаются. кому не лень помогите пожалуйста найти косяк. Весь день глаза мозолю, не могу найти ошибку
    Код (Text):
    1. CalcValsV2_nonMMX:
    2.         shr ecx, 1
    3.  
    4.        .loop:
    5.         mov ax, [esi]
    6.         mov dx, [edi]
    7.         add ax, dx
    8.         shl ax, 1
    9.         shr dx, 1
    10.  
    11.         add dx, ax
    12.         inc dx
    13.         rcr dx, 1
    14.  
    15.         xor dx, ax
    16.         sub ax, dx
    17.         imul dx
    18.  
    19.         xor ax, dx
    20.  
    21.         mov [esi], dx
    22.         mov [edi], ax
    23.         add esi, 2
    24.         add edi, 2
    25.         dec ecx
    26.         jnz .loop
    27.  
    28.         ret
    29.  
    30. CalcValsV2_MMX:
    31.         shr ecx, 3
    32.  
    33.        .loop:
    34.         movq mm0, [esi]
    35.         movq mm1, [edi]
    36.         paddw mm0, mm1
    37.         psllw mm0, 1
    38.         psrlw mm1, 1
    39.  
    40.         pavgw mm1, mm0
    41.         pxor mm1, mm0
    42.         psubw mm0, mm1
    43.  
    44.         movq mm2, mm1
    45.         pmulhw mm1, mm0    ; mm1 - high words
    46.         pmullw mm2, mm0    ; mm2 - low words
    47.  
    48.         pxor mm2, mm1
    49.  
    50.         movq [esi], mm1
    51.         movq [edi], mm2
    52.  
    53.         add esi, 8
    54.         add edi, 8
    55.         dec ecx
    56.         jnz .loop
    57.  
    58.         ret
     
  7. rpy3uH

    rpy3uH New Member

    Публикаций:
    0
    Регистрация:
    14 сен 2006
    Сообщения:
    503
    нашёл.

    Код (Text):
    1. pavgw mm1, mm0
    её аналог с без MMX
    Код (Text):
    1.         add dx, ax
    2.         inc dx       ; <------  CF теряется
    3.         rcr dx, 1
    что делать? реализовывать через edx : eax ?
     
  8. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    add dx, ax
    inc dx
    замени на

    STC
    ADC DX, AX
     
  9. rpy3uH

    rpy3uH New Member

    Публикаций:
    0
    Регистрация:
    14 сен 2006
    Сообщения:
    503
    Pavia, спасибо.
     
  10. MMIX

    MMIX New Member

    Публикаций:
    0
    Регистрация:
    9 дек 2011
    Сообщения:
    385
    Мужики а lea dx, [ax+1] как себя поведет ?
     
  11. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    MMIX
    Никак, просто не скомпилируется. 16битный режим не поддерживает адресацию через ax.
     
  12. MMIX

    MMIX New Member

    Публикаций:
    0
    Регистрация:
    9 дек 2011
    Сообщения:
    385
    Mika0x65
    Точно, чото вообще клинит :)
     
  13. rpy3uH

    rpy3uH New Member

    Публикаций:
    0
    Регистрация:
    14 сен 2006
    Сообщения:
    503
    программа работает в Win32, поэтому проканает только lea edx, [eax+1]. вопрос совершенно в другом, не в том как сложить, а как сделать это наиболее оптимизированно и быстро. lea здесь не катит.
     
  14. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Тогда юзай movzx и 32-битные регистры
    lea edx,[edx+eax+1]
    shr edx,1
    PS: Работа с частичными флагами типа inc+rcr и stc+adc особенно в NetBurst - это еще те тормоза