我将分析和优化一些C代码,因此我首先要检查我想要优化的函数是内存绑定还是cpu绑定。总的来说,我知道,如何做到这一点,但我有一些关于计算浮点运算和分析数据大小的问题。看看下面的for循环,我想分析一下。数组的值是双精度(表示每个8字节):
for(int j=0 ;j<N;j++){
for(int i=1 ;i<Nt;i++){
matrix[j*Nt+i] = matrix[j*Nt+i-1] * mu + matrix[j*Nt+i]*sigma;
}
}
1)你算过多少个浮点运算?我想到了3 *(Nt-1)* N ......但我是否也必须计算数组内的操作(矩阵[j * Nt + i],这个数组的FLOP是2个)?
2)传输了多少数据? 2 *((Nt-1)* N) 8Byte或3 ((Nt-1)* N)* 8Byte。我的意思是,必须加载矩阵的每个条目。计算之后,新值将保存到数组的索引(现在这些是1load和1个存储)。但是这个值用于下一次计算。是否需要另一个加载操作,或者这个值(矩阵[j * Nt + i-1])是否已经可用而没有加载操作?
很多!!!
答案 0 :(得分:0)
使用这种类型的代码,您提议进行的直接分析几乎完全是误导性的。关于代码性能的唯一有意义的信息是实际测量它在实践中运行的速度(基准测试)。
这是因为现代编译器和处理器非常聪明地优化这样的代码,它最终将以一种与您直接分析无关的方式执行。编译器将优化代码,重新排列各个操作。处理器本身会尝试并行执行各个子操作 和/或流水线,以便例如在从内存中提取数据时进行计算。
考虑算法的复杂性,区分O(n)和O(n²)等是有用的,但是常数因素(比如你问大约2 * ......或3 * ......)是完全没有意义的因为它们在实践上有所不同,取决于很多细节。