Почему 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 шт):

Автор решения: MBo

movups на старых процессорах выполняется значительно медленнее movaps (с выровненным адресом) (но вряд ли в 10 раз)

xword[xmm01] стоит записать в регистр и использовать его. Иначе получается доступ к двум разным участкам памяти на каждом обороте цикла

→ Ссылка
Автор решения: Илья К

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

→ Ссылка