Хочу предложить некую подборку маленьких кусочков кода, для стандартных задач, часто встречающихся при программировании на MMX-SSE. Тут никаких откровений не будет, но может кому пригодится.
1. занулить все биты в SSE регистре (xmm0)
pxor xmm0, xmm0
2. выставить все биты в SSE регистре (xmm0)
pcmpeqb xmm0, xmm0
3. дублируем word CX в xmm0
movd xmm0, ecx ; xmm0 = ** ** ** ** | ** ** ** ** | ** ** ** ** | 00 00 VV UU
punpcklwd xmm0, xmm0 ; xmm0 = ** ** ** ** | ** ** ** ** | 00 00 00 00 | VV UU VV UU
pshufd xmm0, xmm0, 0 ; xmm0 = VV UU VV UU | VV UU VV UU | VV UU VV UU | VV UU VV UU
4. дублируем байт CL в xmm0
movd xmm0, ecx ; xmm0 = ** ** ** ** | ** ** ** ** | ** ** ** ** | 00 00 00 UU
punpcklwd xmm0, xmm0 ; xmm0 = ** ** ** ** | ** ** ** ** | 00 00 00 00 | 00 UU 00 UU
pshufd xmm0, xmm0, 0 ; xmm0 = 00 UU 00 UU | 00 UU 00 UU | 00 UU 00 UU | 00 UU 00 UU
movdqa xmm1, xmm0 ; xmm1 = 00 UU 00 UU | 00 UU 00 UU | 00 UU 00 UU | 00 UU 00 UU
psllw xmm1, 8 ; xmm1 = UU 00 UU 00 | UU 00 UU 00 | UU 00 UU 00 | UU 00 UU 00
por xmm0, xmm1 ; xmm0 = UU UU UU UU | UU UU UU UU | UU UU UU UU | UU UU UU UU
5. Перевернуть SSE регистр побайтово
__declspec( align(16) ) static BYTE g_carShufleMask[16] =
{
0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
};
_asm
{
movdqa xmm1, oword ptr [g_carShufleMask]
pshufb xmm0, xmm1
}
Последнее надо использовать аккуратно, pshufb - SSE2 команда (например, MSVC2003 вообще про нее не знает).
На последок. Крайне рекомендую найти и почитать статью "Using Block Prefetch for Optimized Memory Performance" очень хороший пошаговый разбор оптимизации функции memcpy с использованием кеша процессора. Скорость увеличивается в 2.5 раза (по статье в 3, но у меня на четырех компьютерах было от 2 до 2.5). Понятно, что ускорение memcpy (в особенности в тех условиях, которые заявлены в статье) не слишком интересно - но в целом почитать для начинающих вроде меня полезно.
Комментариев нет:
Отправить комментарий