簡體   English   中英

C ++指針向量如何影響性能?

[英]C++ How does a vector of pointers affect performance?

我想知道指向對象的指針的std :: vector如何影響程序的性能,與使用直接包含對象的std :: vector相比。 具體來說,我指的是程序的速度。

我被教導要在其他STL(例如std :: list)上使用std :: vector來提高速度,因為它的所有數據都連續存儲在內存中,而不是碎片化。 這意味着在元素上進行迭代非常快,但是我的想法是,如果我的向量包含指向對象的指針,則對象仍可以存儲在內存中的任何位置,而僅指針是連續存儲的。 我想知道當遍歷向量和訪問對象時,這將如何影響程序的性能。

我當前的項目設計使用指針向量,這樣我就可以利用虛函數了,但是我不確定這是否值得當向量變大時可能遇到的速度下降。 謝謝你的幫助!

正如人們所說,如果需要多態性,則應該存儲指向基址的指針。 如果稍后您確定此代碼很熱並且需要優化它的cpu緩存使用率,則可以通過使對象完全適合緩存通道和/或使用自定義分配器來確保所引用數據的代碼局部性來做到這一點。

切片是當您按Base值存儲對象並復制構造或在其中分配Derived時,Derived將被切片,副本構造函數或分配器僅使用Base並將忽略Derived中的任何數據,在Base中沒有足夠的空間分配取“派生”的完整大小。 也就是說,如果Base為8個字節,Derived為16,即使您提供了明確采用Dervived的副本構造函數/分配器,目標值中Base的8個字節也只有足夠的空間。

我應該說,如果您大量使用優化程序不會忽略的虛擬化,那么真的不值得考慮數據緩存的一致性。 指令高速緩存未命中比數據高速緩存未命中更具破壞性,虛擬化會導致指令高速緩存未命中,因為虛擬化必須在將函數加載到指令高速緩存中之前查找vtable指針,因此不能搶先加載它們。

CPU傾向於喜歡將盡可能多的數據預加載到高速緩存中,如果您加載一個地址,則整個高速緩存通道(〜64字節)將被加載到高速緩存通道中,並且通常還會在此之前和之后加載高速緩存通道。人們為何如此熱衷於數據本地化。

因此,在指針向量的情況下,當您加載第一個指針時,如果實際粒子為16個字節,則一次通過指針加載將在緩存中獲得很多指針,這將觸發緩存未命中並加載該對象周圍的數據。和彼此本地化,您將不會因此損失太多。 如果它們遍及整個堆,那么每次迭代都將獲得非常高速的緩存,並且在處理粒子時相對可以。

傳統上,粒子系統往往非常熱,並且喜歡緊緊打包數據,通常會看到16字節的Plain Old Data粒子系統,您可以通過非常可預測的分支對它進行線性迭代。 這意味着您通常可以在每個高速緩存通道上依靠4個粒子,並使預取器保持在代碼之前。

我還應該說cpu緩存是cpu依賴的,我的重點是intel x86。 例如,arm往往比intel落后很多,而且管道也不太復雜,預取器的能力也較差,因此緩存丟失的破壞性較小。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM