哪个是最快的? boost :: multi_array还是std :: vector?

时间:2013-07-26 17:33:08

标签: c++ arrays performance stdvector boost-multi-array

哪个最快? boost::multi_arraystd::vector? 我将(不是常数)17.179.869元素存储在3个维度中,这些元素需要非常快速且经常地在for循环内访问。表现最好的是什么? std::vectorboost::multi_array

(我不希望它在一秒钟内完成,但我希望它尽可能高效,因为纳秒级差异可以节省大量时间。)

3 个答案:

答案 0 :(得分:3)

最好的建议是自己对它进行基准测试。

在任何情况下,由于您似乎有不变的大小,因此还有其他解决方案:

  • 普通C数组(例如int data[X][Y][Z]
  • 普通的一维C数组,您自己计算索引,例如X*W*H + Y*W + Z,在某些情况下可以很方便
  • std::array,它基本上是一个C ++数组,其中有一些来自STL集合的同义糖
  • std::vector,我猜这是第一个可以尝试的解决方案
  • boost::multi_array,这意味着支持N维数组,因此它可能对您的目的而言过度杀伤,但与矢量相比可能具有更好的数据局部性。

答案 1 :(得分:2)

这些库矢量类设计易于使用且相对故障安全。 它们在设计中的速度和它们一样快,但没有什么能比你自己做的更好(除了手工编码的装配)。 对于你所谈论的大小(2e10元素),我会更关注效率而不是用户友好性。 如果你的最内层循环对每个元素进行非常少的计算,那么你将发现索引计算占主导地位, 这建议做一些展开和指针步进。 (也许你可以指望编译器进行一些展开,但我不关心maybes。)

答案 2 :(得分:2)

唯一可以确定的方法是同时尝试并分析代码。然而,作为一堆想法,这是我认为你会发现的。

  1. 对于您正在处理的大量元素(2e10 +),对元素的访问不会像将这些元素加载到cpu缓存中的缓存压力那样重要。预取者将坐在那里试图加载这些元素,这将占用大部分时间。
  2. 访问2个(或3D)非连续C数组意味着CPU必须从内存的不同部分获取内容。 boost :: multi_array通过幕后存储将其作为一个连续的块进行解决;但这样做有它自己的开销。正如@Jack所说,具有索引的普通1D数组是最好的,即使这样你也可以做一些事情以确保索引最小化。(例如memoization)
  3. 你在循环中所做的工作会显着影响你的时间。分支预测器将成为最大的贡献者。如果它是一个简单的数学运算,没有if / else语句,你可能会获得最佳性能,编译器可能会优化它到SSE指令。如果你有复合类型(而不是int / float / char),那么你将不得不将它们排好以优化访问。
  4. 我几乎建议,尝试两者,然后回来一个新的SO问题,你的循环写,并询问如何优化该部分。几乎总是,编译器可以给出提示,以确保它知道你的意图。
  5. 在一天结束时,试试看