【发布时间】: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 blending、vblendmps 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