如何使用SSE内在函数在非连续内存位置存储值?

Sco*_*ott 5 c sse intrinsics sse2

我是SSE的新手,并使用内在函数优化了一段代码.我对操作本身很满意,但我正在寻找一种更好的方法来编写结果.结果最终有三个_m128i变量.

我要做的是将结果值中的特定字节存储到非连续的内存位置.我现在正在这样做:

__m128i values0,values1,values2;

/*Do stuff and store the results in values0, values1, and values2*/

y[0]        = (BYTE)_mm_extract_epi16(values0,0);
cb[2]=cb[3] = (BYTE)_mm_extract_epi16(values0,2);
y[3]        = (BYTE)_mm_extract_epi16(values0,4);
cr[4]=cr[5] = (BYTE)_mm_extract_epi16(values0,6);

cb[0]=cb[1] = (BYTE)_mm_extract_epi16(values1,0);
y[1]        = (BYTE)_mm_extract_epi16(values1,2);
cr[2]=cr[3] = (BYTE)_mm_extract_epi16(values1,4);
y[4]        = (BYTE)_mm_extract_epi16(values1,6);

cr[0]=cr[1] = (BYTE)_mm_extract_epi16(values2,0);
y[2]        = (BYTE)_mm_extract_epi16(values2,2);
cb[4]=cb[5] = (BYTE)_mm_extract_epi16(values2,4);
y[5]        = (BYTE)_mm_extract_epi16(values2,6);
Run Code Online (Sandbox Code Playgroud)

where y,cbcr是byte(unsigned char)数组.由于我无法定义的原因,这对我来说似乎是错误的.有没有人有更好的方法建议?

谢谢!

Cra*_*rks 9

你基本上不能 - SSE没有散点存储,而且它的设计都围绕着对连续数据流进行矢量化工作的想法.实际上,制作SIMD 涉及的大部分工作都是重新排列数据,使其连续且可矢量化.因此,最好的做法是重新排列数据结构,以便您可以一次写入16个字节.不要忘记,在将SIMD向量中的组件提交到内存之前,可以对其进行重新排序.

如果不这样做,PEXTRWop(_mm_extract_epi16内在函数)几乎是从SSE寄存器中拉出短路并存储到整数寄存器的唯一方法.您可以使用的另一种方法是使用解包和随机操作(_mm_shuffle_ps等)将数据旋转到寄存器的低位字,然后MOVSS/ _mm_store_ss()将该低位字一次存储到存储器中.

您可能会发现使用联合或在SSE和通用寄存器之间移动数据,由于称为加载 - 命中 - 存储停顿的微妙CPU实现细节,将提供非常差的性能.基本上,没有直接的方法在寄存器类型之间移动数据; 处理器必须首先将SSE数据写入存储器,然后再将其读回GPR.在许多情况下,这意味着它必须停止加载操作并等待存储清除,然后才能运行任何进一步的指令.