使用avx内在函数和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记录,在ubuntu中报告)时,它显示累加器的所有元素,y和cumulativeError变量以标量方式逐个计算。
问:如何定义一个内部变量,该内部变量可以保持其“操作顺序”并仍然可以在内部指令中使用(作为矢量化)而不进行优化 -
为了确保它真的是标量,我删除了它变得更快。
有没有办法告诉gcc我需要一个变量/代码矢量化但没有别的东西可以触及?
答案 0 :(得分:3)
如果您只想明确阻止关联数学优化,请不要使用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 ++特定的。)