如何加速非顺序数组填充?

时间:2012-05-13 08:46:41

标签: c++ arrays performance

上下文

我有这样的代码:

..
vector<int> values = ..., vector<vector<int>> buckets;
//reserve space for values and each buckets sub-vector
for (int i = 0; i < values.size(); i++) {
  buckets[values[i]].push_back(i);
}
...

所以我得到一个“桶”,其中包含具有相同值的条目索引。这些桶随后用于进一步处理。

实际上我正在使用本机动态数组(int ** buckets;),但为了简单起见,我使用了上面的向量。

在填充之前我知道每个桶的大小。

载体大小约为2,000,000,000。

问题

正如您可以看到上面的代码以随机方式访问“buckets”数组。因此,它具有持续的高速缓存未命中,从而显着减慢执行时间。 是的,我在个人资料报告中看到了这样的遗漏。

问题

有没有办法提高此类代码的速度?

我试图创建一个辅助向量并在那里放置第一个值,因此我可以在相应的桶中放入两个索引,因为我找到了第二个。这种方法没有给出任何加速。

谢谢!

2 个答案:

答案 0 :(得分:0)

为什么你假设它的缓存未命中会导致代码变慢?您有没有想过或者只是想到了什么?

从性能角度来看,您的代码存在许多问题。第一个也是最明显的是你永远不会保留矢量大小。发生的事情是你的矢量开始非常小(例如,2个元素),然后每次添加超过大小时,它将再次调整并将内容复制到新的存储位置。如果你说有2个十亿条目,你可能会调整大小30次!

在您查看其他改进之前,您需要调用函数vector.reserve()(或vector.resize(),具体取决于哪种行为最适合您)。

修改

真的?你提到你甚至没有在PS中使用矢量?我们如何猜测你的实际代码是什么样的以及它将如何表现?

答案 1 :(得分:0)

对于给定的时间间隔,foo至少是可逆和放射吗?然后,您可以浏览该时间间隔并使用buckets[j](如果bar(j,k)bar的倒数相反)完全填充fook [0,...,MAX_BAR_J) },然后继续j+1等等。

但是,如果foo具有散列属性,则几乎没有机会,因为您无法预测下一个i将为您提供哪个索引。所以我现在看不到任何机会。