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,f是double和T是int.任何包括但不限于内存对齐,并行性,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)
由于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),但可能已经有自动向量化.