首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么gcc/clang不在可能的情况下将128位SIMD本质向量化为256位呢?

为什么gcc/clang不在可能的情况下将128位SIMD本质向量化为256位呢?
EN

Stack Overflow用户
提问于 2022-07-23 04:46:47
回答 1查看 168关注 0票数 1

假设我有这样的函数:

代码语言:javascript
运行
复制
void test32(int* a, int* b, size_t n) {
    for (size_t i = 0; i < n; ++i) {
        a[i] = a[i] + b[i];
    }
}

Clang和gcc在用-O3 -march=core-avx2 (哥德波特)编译时都会产生256位的SIMD .

现在假设我有这样的函数:

代码语言:javascript
运行
复制
void test128(__m128i* a, __m128i* b, size_t n) {
    for (size_t i = 0; i < n; ++i) {
        a[i] = _mm_add_epi32(a[i], b[i]);
    }
}

使用相同的CFLAGS,clang和gcc都拒绝将其矢量化为256位(哥德波特)。

因此,天真代码(自动向量化)每次迭代处理的元素是手动向量化SSE2代码的两倍。这有什么意义?当AVX2可用时,是否有一种方法可以指示编译器将128位SIMD的本质向量化为256位?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-23 05:08:14

不幸的是,我不知道有一个编译器选项可以将本质(或GNU C本机向量)重新向量化为更广泛的类型。,这是首先不对容易自动向量化的情况手动向量化的原因之一。

有时,能够告诉编译器您希望它使用什么向量化策略是有用的,这就是本质的用途。

如果编译器过于积极地重写它们,在某些情况下这将是不好的。就像带有更宽向量的循环之后的清理循环一样,您可能会使用128位来减少标量元素。或者,您可能有16字节对齐,而不是32字节对齐,并且您特别关心沙桥(其中32字节加载/存储错误是非常糟糕的)。或者在Haswell服务器上,256位AVX可以减少最大turbo (至少对于FP数学指令),所以您只想在程序的某些阶段运行的函数中使用256位向量。

从根本上说,这是一种权衡,一种是用asm编写,对于聪明的人来说,指定他们想要的是什么,而只是给出一种方法,以一种它能够理解和优化的方式告诉编译器程序逻辑(就像+操作符:这并不意味着你会得到一个add指令)。

MSVC和ICC比GCC/clang更倾向于从字面上看待本质,而不是不断地通过它们进行传播。GCC/clang关于如何对待本质的选择在很多方面都是明智的。

如果您有这样一个微不足道的向量化问题(没有循环携带依赖项或洗牌),并且希望您的代码可以为将来更广泛的向量指令进行编译,使用OpenMP 来告诉编译器您肯定希望将其向量化。如果不启用完全优化以使编译器尝试自动向量化每个循环,那么OpenMP就是要解决的问题。(在gcc -O3,或叫clang -O2。( -O2 for GCC12.)OpenMP可以使编译器以通常不允许使用-ffast-math的方式将FP数学向量化,例如FP缩减(如数组和)。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73088104

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档