使用 avx intrinsics 和 Kahan 求和算法,我试过这个(只是“加法器”的一部分):
void add(const __m256 valuesToAdd)
{
volatile __m256 y = _mm256_sub_ps(valuesToAdd, accumulatedError);
volatile __m256 t = _mm256_add_ps(accumulator,y);
accumulatedError = _mm256_sub_ps( _mm256_sub_ps(t,accumulator),y);
accumulator = t;
}
没有错误,但是当我检查反汇编(perf record,ubuntu 中的报告)时,它显示了累加器的所有元素,y 和 accumulatedError 变量以标量方式一一计算。
问:如何定义一个内部变量,既可以保持其“操作顺序”,又可以在内部指令中使用(矢量化)而不被优化掉?
为了确保它确实是标量,我删除了 volatile 它变得更快。
有没有办法告诉 gcc 我需要一个向量化的变量/代码,但没有其他可以触及的?
最佳答案
如果您只想明确阻止关联数学优化,请不要使用 volatile
,而是使用函数属性禁用它们:
__attribute__ ((optimize("no-fast-math")))
inline void add(const __m256 &valuesToAdd)
{
__m256 y = _mm256_sub_ps(valuesToAdd, accumulatedError);
__m256 t = _mm256_add_ps(accumulator, y);
accumulatedError = _mm256_sub_ps(_mm256_sub_ps(t, accumulator), y);
accumulator = t;
}
Live Demo .尝试使用编译标志和属性。这个属性似乎不适用于 clang(我想有一些等效的东西,但你的问题是特定于 g++ 的)。
关于c++ - g++ 6.3,avx 内在函数的 Kahan 求和使用 volatile 关键字序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45527193/