Почему SSE листинг выполняется очень медленно?
Есть такой листинг:
xor eax, eax
@@:
movups xmm0, xword[buf+eax]
pxor xmm0, xword[xmm01] ; db 16 dup(0x1)
movups xword[buf+eax], xmm0
add eax, 16
cmp eax, sizeof.buf ; 512
jb @b
(Суть такова: заменить в выделенной области памяти 512 байт нулями или единицами. Если нули — заменить единицами, если единицы — нулями)
И есть такой аналог:
xor ecx, ecx
@@: xor byte[buf+ecx], 0x1
inc ecx
cmp ecx, sizeof.buf
jne @b
Запускаю на своём старом ноутбуке на Intel Pentium 4 и получаю такие результаты:
Первый листинг: 3 601, 3 357, 3 249, 3 243, 3 334 ns
Второй листинг: 3 218, 3 192, 3 564, 3 238, 3 595 ns
В чём проблема? Почему SSE так прошляпился?
Ответы (2 шт):
movups на старых процессорах выполняется значительно медленнее movaps (с выровненным адресом) (но вряд ли в 10 раз)
xword[xmm01] стоит записать в регистр и использовать его. Иначе получается доступ к двум разным участкам памяти на каждом обороте цикла
В современным процессорах ширина шины между процессором и кеш-памятью достигает 16-32 байт, что и позволяет добиться роста скорости при применении SSE для пересылки данных, но в твоем случае ширина шины всего 8 байт, что аннулирует все преимущества SSE при пересылки данных.