相关疑难解决方法(0)

GCC C向量扩展:如何检查任何元素比较的结果是否为真,哪个?

我是GCC的C矢量扩展的新手.根据手册,将一个向量与另一个向量进行比较的结果(test = vec1> vec2;)是"test"在每个元素中包含0,为false,每个元素中为-1为真.

但是如何快速检查是否有任何元素比较是真的?而且,进一步说,如何判断哪个是比较真实的第一个元素?

例如,用:

vec1 = {1,1,3,1};
vec2 = {1,2,2,2};
test = vec1 > vec2;
Run Code Online (Sandbox Code Playgroud)

我想确定"test"是否包含任何真值(非零元素).在这种情况下,我希望"test"减少为true,因为存在一个vec1大于vec2的元素,因此test中的元素包含-1.

另外,或者,我想快速发现WHICH元素未通过测试.在这种情况下,这只是数字2.换句话说,我想测试哪个是第一个非零元素.

int hasAnyTruth = ...; // should be non-zero. "bool" works too since C99
int whichTrue = ...; // should contain 2, because test[2] == -1
Run Code Online (Sandbox Code Playgroud)

我想我们可以使用simd reduction-addition命令(?)将向量中的所有内容加到一个数字中并将该总和与0进行比较,但我不知道如何(或者是否有更快的方法).我猜第二个问题需要某种形式的argmax,但同样,我不知道如何指示GCC在矢量上使用它.

c comparison performance gcc vectorization

14
推荐指数
1
解决办法
768
查看次数

使用向量扩展时让GCC生成PTEST指令

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

例如:

#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;
}
Run Code Online (Sandbox Code Playgroud)

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

.L2:
        vandps  (%rax), %ymm1, %ymm1
        vmovdqa %xmm1, %xmm0
        addq    $32, %rax
        vmovd   %xmm0, %edx
        testl   %edx, %edx
        jne     .L2
        vpextrd $1, %xmm0, %edx …
Run Code Online (Sandbox Code Playgroud)

c gcc sse vectorization avx2

6
推荐指数
1
解决办法
395
查看次数

是什么阻止编译器优化手写的 memcmp()?

鉴于:

#include <string.h>

bool test_data(void *data)
{
    return memcmp(data, "abcd", 4) == 0;
}
Run Code Online (Sandbox Code Playgroud)

编译器可以将其优化为:

test_data:
    cmpl    $1684234849, (%rdi)
    sete    %al
    ret
Run Code Online (Sandbox Code Playgroud)

这很好。

但如果我使用我自己的memcmp()(而不是来自<string.h>),编译器无法将其优化为单个cmpl指令。相反,它这样做:

test_data:
    cmpl    $1684234849, (%rdi)
    sete    %al
    ret
Run Code Online (Sandbox Code Playgroud)
test_data:
    cmpb    $97, (%rdi)
    jne     .L5
    cmpb    $98, 1(%rdi)
    jne     .L5
    cmpb    $99, 2(%rdi)
    jne     .L5
    cmpb    $100, 3(%rdi)
    sete    %al
    ret
.L5:
    xorl    %eax, %eax
    ret
Run Code Online (Sandbox Code Playgroud)

链接: https: //godbolt.org/z/Kfhchr45a

  • 是什么阻止编译器进一步优化它?
  • 我是否做了一些阻碍优化的事情?

c optimization assembly x86-64 memcmp

5
推荐指数
2
解决办法
333
查看次数

标签 统计

c ×3

gcc ×2

vectorization ×2

assembly ×1

avx2 ×1

comparison ×1

memcmp ×1

optimization ×1

performance ×1

sse ×1

x86-64 ×1