2017-08-05 53 views
-1

使用AVX内在和Kahan的总和算法,我已经试过这(只是一个“加法”的部分):G ++ 6.3,对AVX内在Kahan的总和得到系列化与volatile关键字

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,我需要一个变量/代码矢量化,但没有别的要触摸?

+3

你想用'volatile'完成什么?保持局部变量不被优化?你为什么需要这个?对于本地的,基于堆栈的变量,“volatile”没有任何好处。有了那个关键字,编译器显然将对每个float的访问视为一个单独的独立访问,假设它们可以在线性完成(非序列化)时在访问之间改变,所以AVX内在被编码以模拟该行为。 – 1201ProgramAlarm

+0

那么我唯一的选择是使用inline-asm来做不变的有序操作? –

+0

我不知道。我不明白你想要完成什么。 – 1201ProgramAlarm

回答

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 ++的)。

+0

不适合与内联汇编解决方案进行比较。如果性能相当,那么它只值得波音gcc。谢谢 –