Сложение упакованных слов

Тема в разделе "WASM.ASSEMBLER", создана пользователем persicum, 7 окт 2007.

  1. persicum

    persicum New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    947
    Нужно складывать 16-битные слова по модулю FFFF в огромных количествах. Это сделать нетрудно, но обидно, что слова лежат в младших половинках 32-разрядных регистров, соответственно машина работает в полсилы, в старших 16-битах одни нули.

    Вот задачка. Упакуем 16-битные слова в 32-битные регистры по два слова в один регистр. Как по быстрому сложить два 32-разрядных регистра чтобы результат оказался в третьем 32-разрядном регистре, и такой, чтобы его старшие 16-бит это первая сумма по модулю FFFF, а младшие 16-бит - это вторая сумма по модулю FFFF.

    Ну и в заключении, не перепутайте модули 65535 и 65536,
    первый - это 16-бит суммы плюс флаг переноса.
     
  2. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    Используй ММХ/SSE и не парься.
     
  3. persicum

    persicum New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    947
    До SIMD команд я еще не дорос... =(((
     
  4. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    persicum
    А вообще тут путаница у автора, мне кажется. Сложение в ммх/sse происходит по модулю 10000h для вордов, а не 65535 как ТС указывает. Если по модулю 65535, то тут без деления /либо цикла с вычитаниями/ не обойтись имхо. Либо задача нетривиальна, либо автор заблуждается в этом.
     
  5. persicum

    persicum New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    947
    Вообщето мне нужно mod 65535, но я не знаю можно ли на простом ASM_е сложить даже по mod 65536 за раз четыре слова без перепаковки. Имхо по быстрому эти две задачки (mod 65535 или mod 65536) нерешаемы на 32-битных регистрах, нету у проца таких флагов. Дополнительный флаг переноса и флаг четности - какое-то г...но и я не знаю зачем они в машине нужны...

    Через SIMD обе решаемы, поскольку видел такие очень быстрые проги по кодированию.
     
  6. persicum

    persicum New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    947
    Либо с 32-битными подрегистрами xmm регистров, бит переноса будет 17(считая с единицы)
     
  7. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    Короче, сложение по модулю 2 даёт результат 0 или 1. Сложение по модулю 0FFFFh даёт результат с 0 по 0FFFEh. Сложение по модулю не степени двойки - нетривиальная задача, т.к. без деления не обойтись. Сложение по модулям 2, 2^8, 2^16, 2^32 - тривиальные задачи, наиболее быстро решаемые через потоковые/мультимедиа расширения процессора.
     
  8. persicum

    persicum New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    947
    Какое нафиг деление? Ты че?

    add ax,bx
    adc ax,0

    Имеем в ax сумму (ax + bx) mod 65535. Т.е. если нам переполнения пофигу, то это сумма mod 65536, а если мы и его добавили, то это уже mod 65535

    Возможно появление FFFF,
    его можно заменить на 0, если не нравится, или оставить как есть.
     
  9. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    persicum
    http://www.wasm.ru/forum/viewtopic.php?pid=144353#p144353
     
  10. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
  11. persicum

    persicum New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    947
    Black_mirror
    http://rapidshare.com/files/61076526/crc32_9.rar.html
    написал прикола ради очень простой и очень шустрый софтовый RAID. Сырец кодера прилагается. Теперь стоит задачка, для кого-то тривиальная, а кому не очень - ускорить кодер в несколько раз, вплоть до 8 раз! Поскольку там 16-битная арифметика, то 128бит регистров в SSE2 делить на 16бит для слова получается восемь слов за одну команду!!! Нужно всего-то заменить крохотную процедуру умножения-матрицы-на-вектор (а именно, MultVect) на суперский код с SSE2. Остальное следует оставить как есть на языке высокого уровня. Кому интересно, могут спробовать, я пока тайм-аут. Кстати, в этой процедуре умножения-матрицы-на-вектор вместо настоящего умножения - обычное сложение mod 65535, а вместо настоящего сложения - xor. Во как...
     
  12. persicum

    persicum New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    947
    Не так страшен черт как его малюют!
    почитал малость Магду и другие руководства, стал немного просекать.

    На сложение mod 65535 забил, одной командой это не сделаешь,
    (можно было бы например сложить с насыщением и без насыщения, сравнить, результат подправить). Складываю вместо 16-битных слов их дополнения до 32-бит, перенос не теряется.

    Вроде понятно, что можно складывать большие группы слов, можно проксоривать большие группы слов, но есть одно узкое место.
    Нужно произвести замену по таблице.

    Есть:
    xmm0 ! n32_1 ! n32_2 ! n32_3 ! n32_4 !
    xmm1 ! n32_5 ! n32_6 ! n32_7 ! n32_8 !

    нужно по таблице замены засунуть это в регистр

    xmm2 ! n16_1 ! n16_2 ! n16_3 ! n16_4 ! n16_5 ! n16_6 ! n16_7 ! n16_8 !

    так, чтобы n16_1 = [esi + n32_1*4], n16_2 = [esi + n32_2*4] и т.д.

    Скорее всего, без полной перепаковки через регистр eax не обойтись...
    Чем мне тут могут помочь SIMD команды?
     
  13. persicum

    persicum New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    947
    Ничего не получается!!!

    При попытке векторизовать этот код происходит замедление 100%, поскольку перепаковка остается, и xmm команды не спасают,а только добавляются =(((
    Блин, как векторизовать упаковку по таблице (по указателю esi)?


    Код (Text):
    1. Было - восемь раз по 3 команды:
    2. mov eax,[edi]
    3. add eax,[ebp]  //складываем
    4. xor edx,[esi+eax*4] //замена по таблице и накопление результата
    5.  
    6. Стало:
    7. Падение быстродействия в 2 раза...
    8. Но если убрать закомментированный кусок
    9. с перепаковкой по таблице, тогда прирост
    10. производительности в 4 раза (но результат неверный,
    11. разумеется)
    12.  
    13. movdqa xmm0,[edi]
    14. paddd xmm0,[ebp]
    15.  
    16. movdqa xmm1,[edi+16]
    17. paddd xmm1,[ebp+16]
    18.  
    19. movdqa [ebx],xmm0
    20. movdqa [ebx+16],xmm1 //сохранили восемь dword
    21.  
    22. //----Перепаковка-по таблице-----
    23. mov eax,[ebx]
    24. mov eax,[esi+eax*4]
    25. mov word ptr [ebx],ax
    26.  
    27. mov eax,[ebx+4]
    28. mov eax,[esi+eax*4]
    29. mov word ptr [ebx+2],ax
    30.  
    31. mov eax,[ebx+8]
    32. mov eax,[esi+eax*4]
    33. mov word ptr [ebx+4],ax
    34.  
    35. mov eax,[ebx+12]
    36. mov eax,[esi+eax*4]
    37. mov word ptr [ebx+6],ax
    38.  
    39. mov eax,[ebx+16]
    40. mov eax,[esi+eax*4]
    41. mov word ptr [ebx+8],ax
    42.  
    43. mov eax,[ebx+20]
    44. mov eax,[esi+eax*4]
    45. mov word ptr [ebx+10],ax
    46.  
    47. mov eax,[ebx+24]
    48. mov eax,[esi+eax*4]
    49. mov word ptr [ebx+12],ax
    50.  
    51. mov eax,[ebx+28]
    52. mov eax,[esi+eax*4]
    53. mov word ptr [ebx+14],ax
    54. //------------------------
    55.  
    56. xorpd xmm2,[ebx] //проксорили 8 слов одним махом!