- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
背景:GCC C 的内置 vector 扩展允许将 SIMD vector 相当自然地表示为 C“类型”。根据文档,支持许多内置操作(+、- 等)。但是,出于某种原因,三元运算符以及逻辑运算符(&&、||)仅适用于 C++。这是 all=C 代码库的问题。
问题:在 GCC C 中,如何实现以下形式的兼容 SIMD 的 [无分支] 条件:
v4si a = {2,-1,3,4}, b, indicesLessThan0;
indicesLessThan0 = a < 0;
b = indicesLessThan0 ? a : 0;
更一般地说,如何根据相同的结果执行任意独立的语句 block :
v4si c = {9,8,7,6}, d;
for (int i = 0; i < 4; i++) {
if (indicesLessThan0[i]) { // consider tests one by one
b[i] = a[i] // as the ternary operator does above
d[i] = c[i] + 1; // some other independent operation
}
else {
b[i] = 0; // as the ternary operator does above
d[i] = c[i] - 1; // another independent operation
}
}
如果做一个语句 block 更难(SIMD 分支很糟糕),那么可以(假设)以牺牲一些效率为代价对任何额外的语句再次执行三元测试:
d = indicesLessThan0 ? c + 1 : c - 1; // the other operation in the loop
但是由于手册中没有解释的某些原因,三元运算符在 C 中不起作用。还有另一种简单的方法吗?一些使用 if 语句的方法?
最佳答案
我找到了 3 个解决方案,结果是用厨房水槽敲了代码。
切换到 g++。不太难,事实证明,只需在所有 -alloc 之前放置一个 (type *) 即可交换大部分代码。然后我可以这样做:
v16s8 condStor = 测试? a : b;
更好的是,我发现您可以使用 & 和 | 的各种组合来进行 bitbash,就像每个人对整数中的位所做的一样。诀窍是 vector 将所有真值设置为 11111111...(-1 无符号),这使得值在使用按位运算符时保持不变。
v16s8 condStor = b; __builtin_ia32_maskmovdqu (a, test, (char *)(&condStor));
不相信?检查程序集:
pxor %xmm1, %xmm1
movdqa -64(%rbp), %xmm0
pcmpeqb %xmm1, %xmm0
pcmpeqd %xmm1, %xmm1
pandn %xmm1, %xmm0
pxor %xmm1, %xmm1
pcmpgtb %xmm0, %xmm1
movdqa %xmm1, %xmm0
movdqa -32(%rbp), %xmm2
movdqa -16(%rbp), %xmm1
pand %xmm0, %xmm1
pandn %xmm2, %xmm0
por %xmm1, %xmm0
movaps %xmm0, -80(%rbp)
movdqa -64(%rbp), %xmm0
movdqa %xmm0, %xmm1
pand -16(%rbp), %xmm1
pcmpeqd %xmm0, %xmm0
pxor -64(%rbp), %xmm0
pand -32(%rbp), %xmm0
por %xmm1, %xmm0
movaps %xmm0, -80(%rbp)
movdqa -32(%rbp), %xmm0
movaps %xmm0, -80(%rbp)
leaq -80(%rbp), %rax
movdqa -16(%rbp), %xmm0
movdqa -64(%rbp), %xmm1
movq %rax, %rdi
maskmovdqu %xmm1, %xmm0
从 1、2、3 的复杂程度来看,我现在看到了 C++ 抽象的成本。也许这就是 Linus 当年大喊大叫的事情。 (不,可能不会。)无论如何,希望这对某人有所帮助!
关于c - GCC C vector 扩展 : How to test the result of a comparison (for conditional assignment, 等)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31642958/
我是一名优秀的程序员,十分优秀!