簡體   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