PINSR[B/D/Q]的实用程序(使用GCC C向量扩展)



这里有一些幻灯片讨论了这些SSE4.1指令,但我仍然不确定在使用GCC的矢量类型时它们有什么好处。

当我在GCC C中创建vector类型时,按以下方式:

typedef char v16s8 __attribute__ ((vector_size (16)));
v16s8 a = {2,-1,3,4,2,-3,1,5,6,-3,1,0,2,3,-4,2};
int putin = 99;

然后我决定用下面两种方法中的一种输入"putin":

test[1] = putin;
test = __builtin_ia32_vec_set_v16qi (test, putin, 1);

top命令生成一个单独的movb指令,但是第二个命令生成一个movdqa,然后是pinsrb,然后是movaps,然后是movdqa。

假设pinsrb命令仅在您希望保留原始向量创建更改字节的新向量时才有用,从而在一个命令中完成2件事(复制和元素插入),这是正确的吗?

另一个假设:我的测试代码毫无价值,因为GCC实际上只是将字节放入其内部类型中,而从未将其加载回原始的xmm寄存器。但是我也不知道该如何测试。

如果值仍然在内存中,编译器很可能决定使用简单的mov。你应该看看如果它已经在寄存器中会发生什么。另外,不要忘记启用优化,更不用说相关的SSE指令集(-msse4.1)了。

给出这段代码(下次也请自己贴出完整的代码):

typedef char v16s8 __attribute__ ((vector_size (16)));
void foo(v16s8* arg)
{
    v16s8 test = {2,-1,3,4,2,-3,1,5,6,-3,1,0,2,3,-4,2};
    int putin = 99;
    test[1] = putin;
    *arg = test;
}

gcc 5.2 with -O2 -msse4.1生成

movdqa  .LC0(%rip), %xmm0
movl    $99, %eax
pinsrb  $1, %eax, %xmm0
movaps  %xmm0, (%rdi)
ret

最新更新