2012-04-03 40 views
6

將應用程序從32位升級到64位可增加對象的指針大小和內存佔用空間。優化C++中類實例的內存佈局

我正在尋找儘可能減少對象內存佔用的方法。 對於POD結構體,我轉儲結構的內存佈局以找出如何打包成員並減少編譯器填充。

有沒有辦法找出非POD對象(如類實例)的內存佈局? 我怎麼能達到類似對象類包裝的東西?

感謝, 丹

+1

一般會有編譯器特定的標誌和編譯指示,重新排序字段可能會有影響。但是,所有這些都可能會影響性能和互操作性 – sehe 2012-04-03 07:52:15

+0

您正在使用哪種編譯器? – 2012-04-03 07:57:13

+0

@dbbd btw爲什麼你擔心64位體系結構中的進程內存大小? 64位體系結構可以支持巨大的虛擬內存大小。不像32位拱門 – weima 2012-04-03 08:17:53

回答

1

我不知道具體的非POD對象的數據(即虛函數表),即使我想這是由指針大小決定。 無論如何,您可以使用GCCVisual Studio都支持的編譯器指令#pragma pack來控制成員對齊。

您還可以閱讀第7.18段的精彩Agner Fog C++ optimize guide

類或結構的數據成員連續存儲在其 每當創建類或結構的實例聲明的順序。將數據組織到類或結構中不存在性能損失。訪問數據 類或結構對象的成員不比訪問簡單變量花費更多的時間。 大多數編譯器將調整數據成員一輪的地址,以優化訪問

4

您可以使用GCC的-Wpadded通知你其中添加填充,然後根據這些信息重新排列,減少在某些情況下,大小。

強行打包數據對於內存中的表示不是一個好主意。

0

經驗法則:從最大到最小;當元素大小爲2的冪時,這提供了完美的對齊,否則手動優化是可能的。

請注意,即使CPU從違規中恢復,正確對齊對於速度通常也是非常重要的。雖然x86和(AFAIK)x64 CPU的手在第二次讀取時內部沒有對齊內部訪問,但由於工作集較小,讀取未對齊時浪費的時間通常遠大於節省的時間。所以我只會在多個CPU上運行比較時纔會「緊縮」。

對於非POD的,你必須檢查sizeof(element)的。
(如果有噸的對象,我可能會用一個簡單的解析器生成C++去傾倒這些大小)

另外,PVS-Studio具有結構尺寸的分析,並給出了重新排序的建議。我還沒有考慮過它們,但是您可以使用eval來確定它是否適合您。

+0

重新排序成員不是一個簡單的選擇,因爲有很多編碼器/解碼器和其他RPC的東西,這總是令人頭痛的事情。另外,對於IO綁定應用程序,cpu性能並不重要。我寧願打包和放寬CPU,而不是增加性能和鬆散的內存 - 特別是對於這種類型的IO綁定應用程序。 – dbbd 2012-04-03 11:52:51

0

有關非POD對象,我認爲你應該閱讀更多關於vTable,虛擬函數,虛擬繼承來了解哪些事情會傳遞類或對象的大小。實際上,yeilds填充的類對齊,類成員對齊只是影響類的大小的一個因素。

這裏有一些相關的網站,我認爲它可以對你有幫助。

  1. 確定類對象的大小:http://www.cprogramming.com/tutorial/size_of_class_object.html

  2. 內存佈局:http://www.phpcompiler.org/articles/virtualinheritance.html

而且,如果你使用MVSC,你可以轉儲所有類的所有內存佈局在您的解決方案與-d1reportAllClassLayout一樣:

cl -d1reportAllClassLayout main.cpp