【问题标题】:How do I do AVX vector blending with clang native vector syntax (no intrinsics)?如何使用 clang 本机矢量语法(无内在函数)进行 AVX 矢量混合?
【发布时间】:2021-03-07 20:23:54
【问题描述】:

令我高兴的是,我发现 clang 可以让您使用 extended vectors 编写显式矢量代码,而无需借助内在函数。

例如,这段代码:

typedef float floatx16 __attribute__((ext_vector_type(16)));

floatx16 add( floatx16 a, floatx16 b )
{
    return a+b;
}

...将直接转换为带有clang -march=skylake-avx512 调用的单个指令:

vaddps  zmm0, zmm0, zmm1

为了编写无分支代码,我想混合 avx512 向量。 对于内在函数,您将使用 _mm512_mask_blend_ps 内在函数。 (顺便问一下,为什么AVX512使用mask,a,b顺序,而AVX使用a,b,mask顺序?)

尝试使用三元运算符进行混合不起作用:

typedef float floatx16 __attribute__((ext_vector_type(16)));

floatx16 minimum( floatx16 a, floatx16 b )
{
    return a < b ? a : b;
}

...导致...

error: used type 'int __attribute__((ext_vector_type(16)))' (vector of 16 'int' values) where arithmetic or pointer type is required

是否可以在 C 中使用 ext_vector_type(16) 变量来实现 vector blendingvblendmps zmm {k}, zmm, zmm

【问题讨论】:

  • 为什么不想使用内在函数,为什么不使用 avx 框架/库?
  • float16 是一个非常容易混淆的类型名称。大多数人会认为这意味着标量 16 位半精度浮点数。也许floatx16?至于您的实际问题,IDK,clang 很可能能够将一些手动比较 + AND/ANDN/OR 混合优化为比较 + 混合指令,使用标量自动向量化或使用 GNU C / clang 本机向量。 (或者更好的是,vaddps 带有合并掩码,具体取决于您要混合的内容。)
  • 如果你改用vector_size,你会得到很好的gcc和clang矢量化代码:godbolt.org/z/a73TG3
  • @bolov 因为a+b-c_mm256_sub_ps( _mm256_add_ps(a,b), c) 更易读,而且框架越少越好。
  • @bolov 内部函数仅适用于单一架构,而矢量代码可自动适用于 x86、ARM、PowerPC...

标签: c clang simd conditional-operator avx512


【解决方案1】:

(这是@chtz 以答案形式发表的评论:)

至少有两种不同的方式来处理向量类型:

表格 A:

__attribute__ ( ( ext_vector_type(numelements) ) );

表格 B:

__attribute__( ( vector_size(numbytes) ) );

使用表单 A 时,表达式 c ? x : y 将导致编译错误,并带有 clang 11。

更糟糕的是,gcc 10 会默默地假装 ext_vector_type(N) 有 4 个元素,即使 N 是 8 或 16。

当使用表单 B 时,表达式 c ? x : yproperly translated 通过 clang 11 混合成向量。虽然 Clang 10 和 gcc 10 将其转换为不同的东西,但它们都能够编译它。

我不清楚 ext_vector_type 形式存在的原因,尤其是考虑到它的效果有多糟糕。

更新 呃...这仅适用于 C++,但不适用于 C。WHY???

【讨论】:

  • ext_vector_type 本来是个clang的东西,我根本不知道GCC支持它。不过,我不知道它的用途是什么,您已经无法使用 vector_size
  • @PeterCordes 真是一团糟……我发现这只适用于 C++ 而不是 C。呃……然后回到内在函数。
猜你喜欢
  • 2012-08-08
  • 1970-01-01
  • 1970-01-01
  • 2018-12-29
  • 2021-06-10
  • 1970-01-01
  • 2017-05-29
  • 1970-01-01
  • 2010-09-29
相关资源
最近更新 更多