Мелкие задачки для крупных мозгов 10

Тема в разделе "WASM.ZEN", создана пользователем The Svin, 18 мар 2005.

  1. The Svin

    The Svin New Member

    Публикаций:
    0
    Регистрация:
    6 июл 2003
    Сообщения:
    665
    Адрес:
    Russia
    Дано двойное слово и указатель на память.

    Заполнить по указателю память размерами единичных и нулевых строк двойного слова

    например двойное слов

    11101111011001110111110111111111b

    нулевые и единичные строки будут:

    111111111

    0

    11111

    0

    111

    00

    11

    0

    1111

    0

    111

    массив должен быть заполнен значениями

    9,1,5,1,3,2,2,1,4,1,3

    Приоритет в задаче - скорость.
     
  2. vinnie_pooh

    vinnie_pooh New Member

    Публикаций:
    0
    Регистрация:
    30 июн 2004
    Сообщения:
    98
    Код (Text):
    1.     mov eax,0EF677DFFh  ;EAX: value
    2.     mov esi,offset buff ;ESI: pointer
    3.    
    4.     xor ecx,ecx
    5.     xor ebx,ebx
    6.     xor edx,edx
    7.     inc edx     ;EDX: mask
    8.     mov edi,edx     ;EDI: what to search
    9. loop:
    10.     test    eax,edx
    11.     setne   cl
    12.    
    13.     cmp edi,ecx     ;if bit changed
    14.     setne   bl      ;change address
    15.     add esi,ebx
    16.  
    17.     xor edi,ebx     ;if address changed - XOR EDX,1
    18.     inc byte ptr[esi]
    19.     shl edx,1
    20.     jnc loop
     
  3. bogrus

    bogrus Active Member

    Публикаций:
    0
    Регистрация:
    24 окт 2003
    Сообщения:
    1.338
    Адрес:
    ukraine
    Пока так (с циклом):
    Код (Text):
    1.     mov     eax,11101111011001110111110111111111b
    2.     mov     edi,buffer
    3.  
    4.     mov     ecx,eax
    5.     shl     ecx,1
    6.     xor     eax,ecx
    7.     mov     ecx,31
    8.     shr     eax,1
    9.     inc     byte [edi]
    10. @@: shr     eax,1
    11.     adc     edi,0
    12.     inc     byte [edi]
    13.     dec     ecx
    14.     jnz     @b
     
  4. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    Абсолютно ровный код:
    Код (Text):
    1. flsz:;(eax - bit's str, edi - buf) 
    2.     mov ecx,eax
    3.     xor eax,80000000h
    4.     sar ecx,1
    5.     xor eax,ecx
    6. repeat 32
    7.     shr eax,1
    8.     inc byte [edi]
    9.     sbb edx,edx;на атлоне это быстрее
    10.     sub edi,edx;чем adc edi,0
    11. end repeat
    12.     ret
     
  5. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Black_mirror



    Код "ровный" но сильно тормозит на P4 - почти в 1.5 раза хуже, чем цикл bogrus'а. Причина - неудачное расположение inc byte [edi] = false dependence по флагам. Лучше ее поставить перед shr, а еще лучше заменить на add byte [edi],1. Тогда получается быстрее, чем в цикле - но не намного (< 15%).



    А вот существенный выигрыш на P4 получается опять-таки с SETcc. Но надо бы еще на P3 проверить - partial register все-таки.
     
  6. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Вариант с SETcc:
    Код (Text):
    1. macro xxx unroll {
    2.     mov  ecx,11101111011001110111110111111111b
    3.     mov  edi,buffer
    4.     mov  eax,ecx
    5.     add  eax,eax
    6.     xor  eax,ecx
    7.     mov  ecx,2
    8.     add  byte [edi],1
    9.     xor  edx,edx
    10. @@:
    11.     test eax,ecx
    12.     setnz dl
    13.     add  edi,edx
    14.     add  byte [edi],1
    15.     add  ecx,ecx
    16. if unroll = 0
    17.     jnz  @B  ;вариант с циклом
    18. else
    19. repeat 30        ;вариант с разворотом
    20.     test    eax,ecx
    21.     setnz   dl
    22.     add     edi,edx
    23.     add     byte [edi],1
    24.     add     ecx,ecx
    25. end repeat
    26. end if}
    Вариант с циклом: на P3 дает те же результаты, что и вариант bogrus, а на P4 на 20% лучше (204 против 248) и несколько лучше усовершенствованного варианта Black_mirror (216).

    Развернутый вариант (398 байт !): на P3 получается чуть хуже усовершенствованного варианта Black_mirror (130 против 125), но на P4 на 70% лучше (128 против 216).



    PS: попробовал варианты с BSF: ес-но сильная зависимость от числа строк в дворде. Разве только к 11й задачке подойдет для достаточно длинных строк.