3

我有一个算法可以对数组的元素进行一些计算。我想重新使用输入数据缓冲区将结果写入其中。就数据遍历模式而言,它看起来几乎完全一样(在该 for 循环中发生的唯一其他事情是一些指针和计数变量的增量):

int *inputData = /*input data is here */;
for(int i=0;i<some_value;++i)
{
      int result = do_some_computations(*inputData);
      *inputData = result;
      ++inputData;
}

现在有趣的部分:inputData 包含大约 600 万个元素。如果我注释掉对 inputData 数组的写入,那么算法看起来基本上是这样的:

int *inputData = /*input data is here */;
for(int i=0;i<some_value;++i)
{
      int result = do_some_computations(*inputData);
     // *inputData = result;
      ++inputData;
}

该算法经过一系列约 100 次测量,平均耗时约 7 毫秒。但是,如果我留下写入,算法大约需要 55 毫秒。写“*inputData = do_some_computations(*inputData);” 而不是现在的方式对性能没有影响。使用单独的 outputBuffer 也没有什么区别。

这是不好的。该算法的性能对于程序的要求是绝对关键的。我对 7 毫秒很满意,但对 55 毫秒很不满意。

为什么这个单一的回写会导致如此大的开销,我该如何解决?

4

1 回答 1

4

您的代码在非回写版本中被优化为无。为了证明这一点,假设一个 5GHz 单核 CPU 然后:-

7ms = 35,000,000 次循环

600 万个项目 = 35/6 = 每个项目 5.8 个周期 = 没有完成很多工作

对于慢速版本:-

55ms = 275,000,000 个周期

600 万个项目 = 275/6 = 每个项目 45.8 个周期 = 每个项目的工作量要多得多

如果要验证这一点,请查看编译器的程序集输出。

于 2013-01-11T11:19:37.703 回答