Нужно складывать 16-битные слова по модулю FFFF в огромных количествах. Это сделать нетрудно, но обидно, что слова лежат в младших половинках 32-разрядных регистров, соответственно машина работает в полсилы, в старших 16-битах одни нули. Вот задачка. Упакуем 16-битные слова в 32-битные регистры по два слова в один регистр. Как по быстрому сложить два 32-разрядных регистра чтобы результат оказался в третьем 32-разрядном регистре, и такой, чтобы его старшие 16-бит это первая сумма по модулю FFFF, а младшие 16-бит - это вторая сумма по модулю FFFF. Ну и в заключении, не перепутайте модули 65535 и 65536, первый - это 16-бит суммы плюс флаг переноса.
persicum А вообще тут путаница у автора, мне кажется. Сложение в ммх/sse происходит по модулю 10000h для вордов, а не 65535 как ТС указывает. Если по модулю 65535, то тут без деления /либо цикла с вычитаниями/ не обойтись имхо. Либо задача нетривиальна, либо автор заблуждается в этом.
Вообщето мне нужно mod 65535, но я не знаю можно ли на простом ASM_е сложить даже по mod 65536 за раз четыре слова без перепаковки. Имхо по быстрому эти две задачки (mod 65535 или mod 65536) нерешаемы на 32-битных регистрах, нету у проца таких флагов. Дополнительный флаг переноса и флаг четности - какое-то г...но и я не знаю зачем они в машине нужны... Через SIMD обе решаемы, поскольку видел такие очень быстрые проги по кодированию.
Короче, сложение по модулю 2 даёт результат 0 или 1. Сложение по модулю 0FFFFh даёт результат с 0 по 0FFFEh. Сложение по модулю не степени двойки - нетривиальная задача, т.к. без деления не обойтись. Сложение по модулям 2, 2^8, 2^16, 2^32 - тривиальные задачи, наиболее быстро решаемые через потоковые/мультимедиа расширения процессора.
Какое нафиг деление? Ты че? add ax,bx adc ax,0 Имеем в ax сумму (ax + bx) mod 65535. Т.е. если нам переполнения пофигу, то это сумма mod 65536, а если мы и его добавили, то это уже mod 65535 Возможно появление FFFF, его можно заменить на 0, если не нравится, или оставить как есть.
Black_mirror http://rapidshare.com/files/61076526/crc32_9.rar.html написал прикола ради очень простой и очень шустрый софтовый RAID. Сырец кодера прилагается. Теперь стоит задачка, для кого-то тривиальная, а кому не очень - ускорить кодер в несколько раз, вплоть до 8 раз! Поскольку там 16-битная арифметика, то 128бит регистров в SSE2 делить на 16бит для слова получается восемь слов за одну команду!!! Нужно всего-то заменить крохотную процедуру умножения-матрицы-на-вектор (а именно, MultVect) на суперский код с SSE2. Остальное следует оставить как есть на языке высокого уровня. Кому интересно, могут спробовать, я пока тайм-аут. Кстати, в этой процедуре умножения-матрицы-на-вектор вместо настоящего умножения - обычное сложение mod 65535, а вместо настоящего сложения - xor. Во как...
Не так страшен черт как его малюют! почитал малость Магду и другие руководства, стал немного просекать. На сложение 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 команды?
Ничего не получается!!! При попытке векторизовать этот код происходит замедление 100%, поскольку перепаковка остается, и xmm команды не спасают,а только добавляются =((( Блин, как векторизовать упаковку по таблице (по указателю esi)? Code (Text): Было - восемь раз по 3 команды: mov eax,[edi] add eax,[ebp] //складываем xor edx,[esi+eax*4] //замена по таблице и накопление результата Стало: Падение быстродействия в 2 раза... Но если убрать закомментированный кусок с перепаковкой по таблице, тогда прирост производительности в 4 раза (но результат неверный, разумеется) movdqa xmm0,[edi] paddd xmm0,[ebp] movdqa xmm1,[edi+16] paddd xmm1,[ebp+16] movdqa [ebx],xmm0 movdqa [ebx+16],xmm1 //сохранили восемь dword //----Перепаковка-по таблице----- mov eax,[ebx] mov eax,[esi+eax*4] mov word ptr [ebx],ax mov eax,[ebx+4] mov eax,[esi+eax*4] mov word ptr [ebx+2],ax mov eax,[ebx+8] mov eax,[esi+eax*4] mov word ptr [ebx+4],ax mov eax,[ebx+12] mov eax,[esi+eax*4] mov word ptr [ebx+6],ax mov eax,[ebx+16] mov eax,[esi+eax*4] mov word ptr [ebx+8],ax mov eax,[ebx+20] mov eax,[esi+eax*4] mov word ptr [ebx+10],ax mov eax,[ebx+24] mov eax,[esi+eax*4] mov word ptr [ebx+12],ax mov eax,[ebx+28] mov eax,[esi+eax*4] mov word ptr [ebx+14],ax //------------------------ xorpd xmm2,[ebx] //проксорили 8 слов одним махом!