X86 如何使用SSE2加载16 x 8位整数

X86 如何使用SSE2加载16 x 8位整数,x86,sse,simd,sse2,X86,Sse,Simd,Sse2,假设我有16个8位整数,我想使用SSE2将它们加载到\uuuM128i: __m128i v = _mm_set_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); 我可以使用\u mm\u set\u epi8静态地执行此操作,但我希望动态地执行此操作;这些值将在运行时确定 C = userinput; for(int i=0; i<16; i++) { load C*i on v at position i

假设我有16个8位整数,我想使用SSE2将它们加载到
\uuuM128i

__m128i v = _mm_set_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
我可以使用
\u mm\u set\u epi8
静态地执行此操作,但我希望动态地执行此操作;这些值将在运行时确定

C = userinput;
for(int i=0; i<16; i++)
{
    load C*i on v at position i
}
C=userinput;

对于(int i=0;i而言,一种方法是使用并集:

union {
    __m128i v;
    uint8_t a[sizeof(__m128i)];
} u;
将值加载到数组a中,然后从v读回SSE向量


或者,如果您的数据已经在连续内存中,则只需使用
\u mm\u load\u si128
(或者
\u mm\u loadu\u si128
,如果无法保证16字节对齐)。

一种方法是使用并集:

union {
    __m128i v;
    uint8_t a[sizeof(__m128i)];
} u;
将值加载到数组a中,然后从v读回SSE向量

或者,如果数据已经在连续内存中,则只需使用
\u mm\u load\u si128
(或者
\u mm\u loadu\u si128
,如果无法保证16字节对齐)

如果你愿意的话也可以。我也喜欢struct答案,但是如果你在文本中使用指针,你通常需要转换和做指针数学。(这是我的经验。)


如果你愿意这样做,也可以。我也喜欢结构答案,但如果你在文本中使用指针,你通常必须转换并做指针数学。(这是我的经验。)

我不确定这个问题是否得到了回答,但我确信Paul R是正确的

试一试


我不确定这个问题是否得到了回答,但我确信保罗·R是对的

试一试


传递给
\u mm\u set\u epi8
的值不必是常量——在您的示例中,您完全可以编写

__m128i v = _mm_set_epi8(   0,    C,  2*C,  3*C,
                          4*C,  5*C,  6*C,  7*C,
                          8*C,  9*C, 10*C, 11*C,
                         12*C, 13*C, 14*C, 15*C);

(我手头的编译器中没有一个能在这方面做得很好,但它确实能工作。)

传递给
\u mm\u set\u epi8
的值不必是常量——在您的示例中,您完全可以编写

__m128i v = _mm_set_epi8(   0,    C,  2*C,  3*C,
                          4*C,  5*C,  6*C,  7*C,
                          8*C,  9*C, 10*C, 11*C,
                         12*C, 13*C, 14*C, 15*C);

(我手头的编译器中没有一个能在这方面做得很好,但它确实能工作。)

也许你可以用
uint8_t a[sizeof(u m128i)];
替换
uint8_t a[16];
替换为
uint8_t a[sizeof(u m128i)]
?对于您所描述的情况,但对于16位整数,请使用您现在正在使用的常量(
set(1,2,3,4…)
),然后将其乘以
set1(用户输入)
。广播很容易/便宜,但没有在寄存器中生成序列的指令。
\mm\u set\u epi8(C*1,C*2…)在大多数编译器上,
会编译成大量的标量乘法。对于您描述的情况,但使用16位整数,请像现在一样使用常量(
set(1,2,3,4…)
),然后将其乘以
set1(用户输入)
。广播很容易/便宜,但没有在寄存器中生成序列的指令。
\u mm\u set\u epi8(C*1,C*2,…)
会在大多数编译器上编译成大量的标量倍数。
__m128i v = _mm_set_epi8(   0,    C,  2*C,  3*C,
                          4*C,  5*C,  6*C,  7*C,
                          8*C,  9*C, 10*C, 11*C,
                         12*C, 13*C, 14*C, 15*C);