嗯,我在英特尔编译器优化(ICC)方面遇到了一些麻烦。一般说来,我想使用ICC循环自动矢量化。早些时候,我使用了显式向量化循环和函数。据我所知,英特尔编译器允许有标量和相应的矢量化功能,通过_declspec(vector_variant())
功能。但我对此有些意见。例如,目前我有两个版本的函数:
int plus(int a, int b)
{
return a + b;
}
__m256i plus_avx(__m256i a, __m256i b)
{
return _mm256_add_epi32(a, b);
}
int main()
{
int aa[1000] = { 2 };
int bb[1000] = { 4 };
int cc[1000] = { 0 };
for (int i = 0; i < 1000; ++i)
cc[i] = plus(aa[i], bb[i]);
}
我希望ICC使用矢量化的函数,用于自动矢量化循环。我尝试使用__declspec(vector_variant())
,比如:
_declspec(vector_variant(implements(plus(int a, int b)), vectorlength(8))) __m256i plus_avx(__m256i a, __m256i b)
{
return _mm256_add_epi32(a, b);
}
但我犯了错误:
1>error #15508:函数的向量变体'?plus_avx@@YA?AT__m256i@@T1@0@Z‘的不正确返回类型?加上位置0处的@@YAHJH@Z。 1>正确的原型是:' __m128i,__m128i ?plus_avx@@YA?AT__m256i@@T1@0@Z(__m128i v0_0,__m128i v0_1,__m128i v1_0,__m128i v1_1)‘。
为什么编译器需要 __m128i ,以及是否有方法使用__m256i insted of __m128i
注意:它用于ICC的/QaxCORE 2标志。
发布于 2018-02-08 05:22:28
最后我解决了我的问题。也许这对其他人来说会很有趣。
解决方案是使用处理器子句:
( _declspec(vector_variant(implements(plus(int a,int b),向量长度(8),处理器(Core_4th_gen_avx)
发布于 2018-02-05 22:45:33
AFAIK,没有办法获得自动矢量化来使用自定义原语。只需告诉您的编译器您的数组是对齐的,让它使用+
而不是_mm256_add_epi32
从纯ISO +
自动向量化。
编译器选项控制自动矢量化的默认矢量宽度.(例如,针对skylake- max 512,ICC和其他编译器默认使用256 b向量,因为实际上使用512 b矢量可以减少最大涡轮时钟,并且只有当程序将大部分时间用于矢量循环时才值得使用。编译器不知道这一点。)
例如,gcc有一个-mprefer-avx128
自动矢量化与128位AVX指令,即使AVX2 256位整数指令是可用的。
ICC18引入了-qopt-zmm-usage:low|high
,对于Skylake服务器默认使用low
,对于Xeon默认使用high
,因为Xeon是设计在512位向量附近的,但是Skylake- max 512必须降低其最大turbo来运行512位指令。(在Skylake上的较窄的向量上使用AVX512指令是不受惩罚的,但Xeon甚至不允许这样做,因为它不支持AVX512的AVX512VL (向量-legnth)子集。)
我不知道ICC如何控制128位对256位的auto-vectorization,,但它绝对不是通过编写函数使用本质。
https://stackoverflow.com/questions/48628101
复制