Модулярная арифметика. Сложение.

Тема в разделе "WASM.ASSEMBLER", создана пользователем Gray, 10 ноя 2004.

  1. Gray

    Gray New Member

    Публикаций:
    0
    Регистрация:
    6 окт 2004
    Сообщения:
    75
    Адрес:
    Russia
    Речь идет о сложении чисел в системе остаточных классов. (см. Модулярная арифметика, например у Кнута или Система Остаточных Классов (СОК) (Юдицкий, Акушский)). Ссылка в тему: http://www.borz.ru/articles/sok/sok.html



    Пусть в регистре xmm0 находится вектор модулей pv ( 16 модулей p i=0...15 по байту на каждый), в регистре xmm1 находится вектор xv (остатки от деления некого числа X на сооветствующие модули)( x=X mod(p) ), а в регистре xmm2 аналогичный вектор yv ( y=Y mod(p) ).

    Хочется максимально быстро получить в регистре xmm3 сумму xv+yv по модулю pv (z=(x+y) mod(p).



    Код работающий у меня сейчас:



    ; xmm0 - p

    ; xmm1 - x

    ; xmm2 - y

    movdqa xmm3,xmm1

    paddb xmm3,xmm2

    movdqa xmm7,xmm3

    pminub xmm7,xmm0

    pcmpeqb xmm7,xmm0

    pand xmm7,xmm0

    psubb xmm3,xmm7 ; xmm3=z=(x+y) mod(p)



    Это работает при условии, что все p<128, или p=256

    Если p<64, то можно сделать быстрее:



    movdqa xmm3,xmm1

    paddb xmm3,xmm2

    movdqa xmm7,xmm3

    pcmpgtb xmm7,xmm0

    pand xmm7,xmm0

    psubb xmm3,xmm7 ; xmm3=z=(x[i]+y[i]) mod(p[i])



    Как бы посчитать это еще быстрее да и для любых p[i]<=256 ???[/i][/i][/i][/i]