gpt4 book ai didi

c - 使用 vector 扩展时让 GCC 生成 PTEST 指令

转载 作者:太空狗 更新时间:2023-10-29 17:25:03 24 4
gpt4 key购买 nike

当使用 C 的 GCC vector 扩展时,如何检查 vector 上的所有值是否为零?

例如:

#include <stdint.h>

typedef uint32_t v8ui __attribute__ ((vector_size (32)));

v8ui*
foo(v8ui *mem) {
v8ui v;
for ( v = (v8ui){ 1, 1, 1, 1, 1, 1, 1, 1 };
v[0] || v[1] || v[2] || v[3] || v[4] || v[5] || v[6] || v[7];
mem++)
v &= *(mem);

return mem;
}

SSE4.2 有 PTEST 指令,它允许运行像用作 for 条件的测试,但 GCC 生成的代码只是解压 vector 并检查单个元素一个一个:

.L2:
vandps (%rax), %ymm1, %ymm1
vmovdqa %xmm1, %xmm0
addq $32, %rax
vmovd %xmm0, %edx
testl %edx, %edx
jne .L2
vpextrd $1, %xmm0, %edx
testl %edx, %edx
jne .L2
vpextrd $2, %xmm0, %edx
testl %edx, %edx
jne .L2
vpextrd $3, %xmm0, %edx
testl %edx, %edx
jne .L2
vextractf128 $0x1, %ymm1, %xmm0
vmovd %xmm0, %edx
testl %edx, %edx
jne .L2
vpextrd $1, %xmm0, %edx
testl %edx, %edx
jne .L2
vpextrd $2, %xmm0, %edx
testl %edx, %edx
jne .L2
vpextrd $3, %xmm0, %edx
testl %edx, %edx
jne .L2
vzeroupper
ret

有没有什么方法可以让 GCC 生成有效的测试,而无需恢复使用内在函数?

更新:作为引用,使用不可移植的 GCC 内置代码为 (V)PTEST:

typedef uint32_t v8ui __attribute__ ((vector_size (32)));
typedef long long int v4si __attribute__ ((vector_size (32)));

const v8ui ones = { 1, 1, 1, 1, 1, 1, 1, 1 };

v8ui*
foo(v8ui *mem) {
v8ui v;
for ( v = ones;
!__builtin_ia32_ptestz256((v4si)v,
(v4si)ones);
mem++)
v &= *(mem);

return mem;
}

最佳答案

gcc 4.9.2 -O3 -mavx2(在 64 位模式下)没有意识到它可以为此使用 ptest|||

| 版本使用vmovdvpextrd 提取 vector 元素,并结合7 insns 32位寄存器之间。所以这很糟糕,并且没有利用任何仍会产生相同逻辑真值的简化。

|| 版本同样糟糕,同样一次提取一个元素,但是执行了一个test/ jne 为每一个。

所以在这一点上,您不能指望 GCC 能识别这样的测试并做任何远程高效的事情。 (pcmpeq/movmsk/test 是另一个不错的序列,但 gcc 也不会生成它。)

关于c - 使用 vector 扩展时让 GCC 生成 PTEST 指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29472524/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com