C 如何使用铿锵的本机向量语法(无内部函数)进行AVX向量混合?

C 如何使用铿锵的本机向量语法(无内部函数)进行AVX向量混合?,c,clang,simd,conditional-operator,avx512,C,Clang,Simd,Conditional Operator,Avx512,令我高兴的是,我发现clang可以让您编写显式向量代码,而无需借助内部函数,使用 例如,此代码: typedef float floatx16 __attribute__((ext_vector_type(16))); floatx16 add( floatx16 a, floatx16 b ) { return a+b; } …将通过调用直接转换为单个指令: vaddps zmm0, zmm0, zmm1 为了编写无分支代码,我想混合avx512向量。 对于intrinsic,

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

例如,此代码:

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

floatx16 add( floatx16 a, floatx16 b )
{
    return a+b;
}
…将通过调用直接转换为单个指令:

vaddps  zmm0, zmm0, zmm1
为了编写无分支代码,我想混合avx512向量。 对于intrinsic,您可以使用
\u mm512\u mask\u blend\u ps
intrinsic。(顺便问一下,为什么AVX512使用掩码,a,b顺序,而AVX使用a,b,掩码顺序?)

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

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

floatx16 minimum( floatx16 a, floatx16 b )
{
    return a < b ? a : b;
}
是否可以使用C中的ext\u vector\u type(16)变量执行,
vblendmps zmm{k},zmm,zmm

(这是@chtz在回答形式中的注释:)

至少有两种不同的方法来创建向量类型:

表格A:

\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

表格B:

\uuuuuuuuuuuuuuuuuuu属性((向量大小(numbytes))

当使用表单A时,表达式
c?x:y
将导致clang 11的编译错误

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

当使用表格B时,表达式
c?x:y
通过叮当声11进入矢量混合。尽管Clang10和GCC10将其转换为不同的内容,但它们都能够编译它

我不清楚为什么存在ext_vector_类型的表单,特别是考虑到它的工作有多糟糕

更新
啊。。。这只能在C++中工作,而不能在C.<强>为什么??> /强> < /p>为什么不使用内联函数,为什么不使用AVX框架/库?<代码> FLUAT16是一个非常混乱的类型名称。大多数人认为这意味着标量16位半精度浮点。也许
floatx16
?至于您的实际问题,IDK、clang可能能够通过标量自动矢量化或GNU C/clang本机向量优化一些手动比较+和/和/或混合到比较+混合指令中。(或者更好的是,一个带有合并屏蔽的
vaddps
,这取决于你混入的内容。)如果你用
vector\u size
来代替,你会得到很好的gcc和clang的矢量化代码:@bolov,因为
a+b-c
\u mm256\u sub\u ps(\u mm256\u add\p(a,b),c)
和更少的框架更清晰,更好的。@bolov内部函数仅适用于单个体系结构,而矢量代码适用于x86、ARM、PowerPC。。。自动
ext\u vector\u type
最初是一个叮当作响的东西,我根本不知道GCC支持它。我不知道这是为了什么,虽然,你不能用
vector\u size
@PeterCordes多乱啊。。。我发现这只在C++中工作,而不是在C…那么,回到本质上来吧。
error: used type 'int __attribute__((ext_vector_type(16)))' (vector of 16 'int' values) where arithmetic or pointer type is required