这个c/c ++循环可以优化多少?

leo*_*on 2 c c++ optimization performance loops

我是优化的新手.我一直在阅读有关如何优化c ++代码的一些参考,但我很难将它应用于实际代码.因此,我只想收集一些关于如何从下面的循环中尽可能多地从CPU /内存中挤出汁液的真实世界优化技术

double sum = 0, *array;
array = (double*) malloc(T * sizeof(double));
for(int t = 0; t < T; ++t){
sum += fun(a,b,c,d,e,f,sum);
*(array+t) = sum;
}
Run Code Online (Sandbox Code Playgroud)

这里a,b,c,d,e,fdoubleTint.任何包括但不限于内存对齐,并行性,openmp/MPI和SSE指令的内容都是受欢迎的.编译器是标准的gcc,microsoft或常用的编译器.如果解决方案是特定于编译器的,请具体编译器和任何与您的解决方案关联的选项标志

谢谢!

PS:忘了提及物业fun.请假设它是一个简单的函数,里面没有循环,只包括基本的算术运算.简单地将其视为内联函数.

EDIT2:由于细节fun很重要,请忘记参数c,d,e,f并假设fun定义为

inline double fun(a,b, sum){
return sum + a* ( b - sum);
}
Run Code Online (Sandbox Code Playgroud)

ken*_*ytm 7

由于sum以非平凡的方式依赖于其先前的值,因此无法并行化代码(因此OpenMP和MPI已经完成).

应使用适当的编译器设置自动强制执行/使用内存对齐和SSE.

除了内联fun和展开循环(通过编译-O3)之外,如果fun完全是通用的,我们无能为力.


因为fun(a,b,sum) = sum + a*(b-sum),我们有封闭的形式

            ab             t+1
array[t] = ———— ( 1 - (2-a)    )
            a-1 
Run Code Online (Sandbox Code Playgroud)

可以进行矢量化和并行化,但除法和取幂可能非常昂贵.

然而,对于封闭形式,我们可以从任何索引开始循环,例如创建2个线程,一个从t = 0到T/2-1,另一个从t = T/2到T-1,它们执行原始循环,但是sum使用上述封闭形式的解决方案计算初始值.此外,如果只需要数组中的一些值,则可以懒惰地计算.

对于SSE,您可以先用数据填充数组(2-a)^(t+1),然后应用于x :-> x - 1整个数组,然后应用于x :-> x * c整个数组c = a*b/(1-a),但可能已经有自动向量化.

  • @phk:请参阅OP的更新! (4认同)