如何将现有的矢量化函数与Intel编译器自动化的现有标量函数相关



好吧,我在英特尔编译器优化(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>错误#15508:矢量变体的不正确返回类型 '?plus_avx @@ ya?at__m256i @@ t1@t1@0@z'of function'?plus @@ @@ yahjh@z'at 位置0。

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设置为__M128I

注意:ICC的使用/qaxcore-avx2标志。

最后我解决了我的问题。也许对别人来说会很有趣。

解决方案正在使用处理器子句:

_declSpec(vector_variant(insterments(plus(int a,int b((,vectorLength(8(,处理器(core_4th_gen_avx(((

afaik,无法获得自动矢量化来使用自定义基础。只需告诉您的编译器您的数组是对齐的,然后使用+而不是_mm256_add_epi32

编译器选项控制自动矢量化的默认向量宽度。(例如,针对Skylake-AVX512,ICC和其他一些编译器默认用于使用256B矢量,因为实际上使用512B矢量会减少最大涡轮时钟,并且只有在该程序将大部分时间用于矢量化loops。知道这一点。(

例如,即使有AVX2 256BIT Integer指令,GCC也具有-mprefer-avx128可以自动使用128位AVX指令。

ICC18引入了-qopt-zmm-usage:low|high,用于Skylake-Server的low和Xeon-Phi的high,因为Xeon-Phi的设计量约为512位矢量,但是Skylake-avx512必须降低其Max turbo才能运行512-BIT指令。(对于Skylake上的较窄向量使用AVX512说明没有罚款,但是Xeon Phi甚至不允许这样做,因为它不支持AVX512的AVX512VL(Vector-Legnth(子集。(

。( 。

我不确定ICC如何控制128位与256位 auto - vectorization,但绝对不是使用Interinsics编写功能。

最新更新