繁体   English   中英

嵌套向量与连续数组的性能影响

[英]Performance Impact of Nested Vectors vs. Contiguous Arrays

有没有可靠的测试清楚地显示访问和写入嵌套向量与C ++的内置数组之间的性能差异? 我听说使用嵌套(多维)向量通常比访问单个数组中的元素(其中所有元素都存储在连续的内存中)有一些性能开销,但这对我来说似乎只是假设。 我还没有看到任何实际显示这些差异的测试。 它们重要吗? 我确信它取决于场景,但作为一个缺乏经验的程序员,我不太确定这些差异在多大程度上变得显着。

这绝对取决于场景,在某种程度上我认为不可能以一般方式回答哪种方法最快。 最快的方法是访问模式具有最佳数据局部性的方法 - 这在很大程度上取决于访问模式以及结构在内存中的布局方式,在嵌套向量的情况下依赖于分配器并且可能在编译器之间有很大差异。

我遵循优化的一般规则,即首先以最直接的方式编写内容,然后在证明存在瓶颈时尝试优化。

有两件事会导致嵌套和扁平数组之间的运行时差异:
缓存行为和间接

  • CPU使用Caches层次结构来避免过于频繁地访问RAM。 这利用了大多数存储器访问是连续的或具有某个时间局部性的事实,即最近访问的内容将很快再次访问。
    这意味着如果嵌套数组的最内层数组相当大,那么如果以连续方式迭代值 ,则会注意到平面数组的差异很小甚至没有差异。 这意味着当迭代一系列值时,对于平面数组,最内层循环应迭代连续元素,对于嵌套数组,最内层循环应迭代最内层数组。
  • 但是,如果您的访问模式是随机的,则时间上最重要的差异是间接:
    对于平面数组,使用类似A[(Z * M + Y) * N + X] ,因此您可以执行4次算术运算,然后进行内存访问。
    对于嵌套数组,使用A[Z][Y][X] ,因此实际上存在三个相互依赖的内存访问:在访问A[Z][Y]之前需要知道A[Z] A[Z][Y] ,依此类推。 由于现代CPU的超标量体系结构,可以并行执行的操作特别有效,相互依赖的操作不是那么多。 所以你有一些算术运算和一侧的内存负载和另一侧的三个相互依赖的负载,这明显更慢。 这可能是可能的,嵌套数组,内容AA[Z]对于一些值Z可以在高速缓存层次结构发现,但如果你的嵌套数组足够大,它永远不会完全放入高速缓存,因此导致多个高速缓存未命中和内存加载(嵌套),而不是单个高速缓存未命中和加载(平坦),用于对阵列的单个随机访问。

另请参阅他的问题 ,尤其是下面的简短答案,以便更详细地讨论缓存(我的答案)和间接(Peter的答案),这也提供了一个示例,其中嵌套和平面数组之间没有明显的差异(在修复索引错误之后)当然 ;) )

因此,如果您想知道它们之间是否存在重大的运行时差异,我的答案是:

  • 如果您进行随机访问,您肯定会注意到多个间接,从而导致嵌套数组的运行时间更长。

  • 如果你进行连续访问使用正确的循环排序(最内层循环=最内层数组/平面数组最里面的索引) 并且你的多维数组的最内层维度足够大,那么差异将是可忽略的,因为编译器将能够将所有间接移出最内层的循环。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM