【发布时间】:2012-01-25 15:00:52
【问题描述】:
我有以下C++代码sn-p(C++部分是profiler类,这里省略),用VS2010(64位Intel机器)编译。该代码只是将浮点数数组 (arr2) 与一个标量相乘,然后将结果放入另一个数组 (arr1):
int M = 150, N = 150;
int niter = 20000; // do many iterations to have a significant run-time
float *arr1 = (float *)calloc (M*N, sizeof(float));
float *arr2 = (float *)calloc (M*N, sizeof(float));
// Read data from file into arr2
float scale = float(6.6e-14);
// START_PROFILING
for (int iter = 0; iter < niter; ++iter) {
for (int n = 0; n < M*N; ++n) {
arr1[n] += scale * arr2[n];
}
}
// END_PROFILING
free(arr1);
free(arr2);
为简单起见,此处省略了从文件读取部分和分析(即运行时测量)。
当arr2 被初始化为[0 1] 范围内的随机数时,与arr2 被初始化为稀疏数组的情况相比,代码的运行速度大约快10 倍,其中大约2/3 的值为零。我玩过编译器选项/fp 和/O,它们稍微改变了运行时间,但大约保持了1:10 的比例。
- 为什么性能取决于实际值? CPU 有何不同之处使稀疏数据的运行速度慢了约 10 倍?
- 有没有办法让“慢数据”运行得更快,或者任何优化(例如向量化计算)对两个数组都有相同的效果(即“慢数据”仍然会比“快数据”运行得更慢数据”)?
编辑
完整代码在这里:https://gist.github.com/1676742,用于编译的命令行在test.cpp的注释中。
数据文件在这里:
【问题讨论】:
-
请您提供两个测试的完整、可编译的版本,以便我们进行实验?
-
会不会是当您将
0传递给稀疏矩阵中的浮点数时,从int到float的转换会引入一些开销? -
你只更新不为0的元素?那么,会不会是零不在缓存中呢?
-
@duedl0r:我也有这个想法。但是,此参数仅适用于 20,000 的第一次迭代,因为加法循环遍历整个数组。
-
@aix:嗯,是的,你可能是对的。但是你永远不知道编译器会生成 :) 在这种情况下,他可以切换 for 循环,所以
niter循环是内部循环,不是吗?如果他真的疯了,也许他甚至会生成arr1[n] += niter * scale * arr2[n];)
标签: c++ c performance visual-studio-2010