169 похожих чатов

Добрый вечер коллеги, пришла в голову идея заняться оптимизацией своих

старых проектов, и столкнулся с очень странным парадоксом. Мой любимый compiler explorer убеждает меня, что использование SIMD (см. пример 1) в 6 раз ускоряет процесс и вообще все быстро и скоро, однако запуская все это дело в профайлере оказывается, что в реале оно медленнее аж в 2 раза.

Версия с SIMD (страничка с compiler explorer https://godbolt.org/z/93v49MWWx)
section .data
mask: db 00h, 05h, 0Ah, 0Fh, 04h, 09h, 0Eh, 03h, 08h, 0Dh, 02h, 07h, 0Ch, 01h, 06h, 0Bh

section .text
;rcx -> address of block
_ShiftRows:
movdqu xmm1, [rcx]
mov rax, mask
movdqu xmm2, rax
pshufb xmm1, xmm2
movdqu [rcx], xmm1
ret

Версия без SIMD (https://godbolt.org/z/q1bKPbxWK)
_ShiftRows:
mov dl, [rcx + 1]
mov al, [rcx + 5]
mov [rcx + 1], al
mov al, [rcx + 9]
mov [rcx + 5], al
mov al, [rcx + 13]
mov [rcx + 9], al
mov [rcx + 13], dl

mov dl, [rcx + 2]
mov al, [rcx + 10]
mov [rcx + 10], dl
mov [rcx + 2], al

mov dl, [rcx + 6]
mov al, [rcx + 14]
mov [rcx + 6], al
mov [rcx + 14], dl

mov dl, [rcx + 3]
mov al, [rcx + 15]
mov [rcx + 3], al
mov al, [rcx + 11]
mov [rcx + 15], al
mov al, [rcx + 7]
mov [rcx + 11], al
mov [rcx + 7], dl
ret
Вопрос собственно, почему так происходит, несмотря на миллион обращений к стаку, второй пример всеравно быстрее оказывается?

10 ответов

7 просмотров

Чего... Второе никак не может исполниться быстрее.

А как ты мерял время?

Dog_with_a_Tail- Автор вопроса

К тому же, у тебя такты расписаны на каждую инструкцию в [2], и в первом варианте - 79, во втором всего 15. Не знаю, куда ты смотришь.

попробуй выровнять данные. 16 байт там вроде, точнее надо гуглить

Dog_with_a_Tail- Автор вопроса
Aiwan \ (•◡•) / _bot
попробуй выровнять данные. 16 байт там вроде, точн...

Да не поможет, там же всё по тактам расписано, и пропускную способность добавили в [3]. SIMD по тактам намного быстрее исполнится, чем тот код без SIMD. И даже если пропускную способность учитывать - не поможет. К тому же, там работа с 16-ти битными регистрами, что на некоторых процессорах даёт большую задержку (читал у Агнера Фога давно). Тут без вариантов.

Dog_with_a_Tail
Не очень понял, что имеешь в виду

многие инструкции sse требуют выровненые данные по параграфу (16 байт). инструкции которые не требуеют этого выравнивания работают со штрафом по времени или не работают вообще (надо уточнять). примерно так я это понимаю

Dog_with_a_Tail- Автор вопроса
Aiwan \ (•◡•) / _bot
многие инструкции sse требуют выровненые данные по...

Я так понял нужно movdqa вместо movdqu, но это ничего не меняет

Dog_with_a_Tail
Я так понял нужно movdqa вместо movdqu, но это нич...

movdqa быстрее чем movdqu на сотые доли секунд за миллионы операций, т.е. быстрее на где то 0,000002~0,000005%. В movdqu словно на архитектурном уровне встроили обработчик исключений невыровненности данных, с минимальным пенальти для случая выравненных данных, т.е. там где movdqa сгенерирует исключение невыровненных данных, там в случае movdqu микрокод процессора сам обработает подобное исключение. Т.е. movdqu дольше чем movdqa ровно на регистрацию обработчика исключений в микрокоде, и очистку регистрации - это пара инструкций микрокода против сотен инструкций микрокода зашитых в симд инструкциях.

Похожие вопросы

Обсуждают сегодня

30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
13
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
Ребят в СИ можно реализовать ООП?
Николай
33
Как передать управляющий символ в открытую через CreateProcess консоль? Собсна, есть процедура: procedure TRedirectThread.WriteData(Data: OEMString); var Written: Cardinal;...
Serjone
6
в JclConsole объявлено так: function CtrlHandler(CtrlType: DWORD): BOOL; stdcall; - где ваше объявление с stdcall? у вас на картинке нет stdcall
Karagy
8
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
program test; {$mode delphi} procedure proc(v: int32); overload; begin end; procedure proc(v: int64); overload; begin end; var x: uint64; begin proc(x); end. Уж не знаю...
notme
6
Карта сайта