gpt4 book ai didi

c - GCC C vector 扩展 : How to test the result of a comparison (for conditional assignment, 等)?

转载 作者:太空狗 更新时间:2023-10-29 15:32:16 25 4
gpt4 key购买 nike

背景: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 个解决方案,结果是用厨房水槽敲了代码。

  1. 切换到 g++。不太难,事实证明,只需在所有 -alloc 之前放置一个 (type *) 即可交换大部分代码。然后我可以这样做:

    v16s8 condStor = 测试? a : b;

  2. 更好的是,我发现您可以使用 & 和 | 的各种组合来进行 bitbash,就像每个人对整数中的位所做的一样。诀窍是 vector 将所有真值设置为 11111111...(-1 无符号),这使得值在使用按位运算符时保持不变。

  3. 更好的是,“输入双关语 101”具有内在功能:
    v16s8 condStor = b; __builtin_ia32_maskmovdqu (a, test, (char *)(&condStor));
    这利用了专用于一口气完成#2 功能的功能。

不相信?检查程序集:

  1. 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)
  2. 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)
  3. 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/

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