2012-04-03 7 views
6

アプリケーションを32ビットから64ビットにアップグレードすると、オブジェクトのポインタサイズとメモリフットプリントが増加します。C++でクラスインスタンスのメモリレイアウトを最適化する

私は可能な限りオブジェクトのメモリフットプリントを減らす方法を探しています。 POD構造体の場合、構造体のメモリレイアウトをダンプして、メンバーをパックし、コンパイラのパディングを減らす方法を理解します。

クラスインスタンスなどの非PODオブジェクトのメモリレイアウトを把握する方法はありますか? クラスオブジェクトのパッキングに似た何かを達成できますか?私は特定の非PODのことは知らない

おかげで、 ダン

+1

一般的にはコンパイラ固有のフラグとプラグマであり、フィールドの順序を変更すると効果があります。ただし、これはパフォーマンスと相互運用性に影響する可能性があります – sehe

+0

どのコンパイラを使用していますか? –

+0

@dbbd btwなぜ64ビットアーキテクチャでプロセスメモリサイズが心配ですか? 64ビットアーキテクチャは、巨大な仮想メモリサイズをサポートすることができます。 32ビットアーチとは異なり – weima

答えて

1

は、私はそれは、ポインタのサイズによって決定されているとしていても、(すなわち、vtableの)データオブジェクト。 とにかく、GCCVisual Studioの両方でサポートされているコンパイラ指示文#pragma packを使用して、メンバーの配置を制御することができます。

あなたがまた素晴らしいAgner Fog C++ optimize guide上のパラグラフ7.18を読むことができます:

をクラスまたは構造体のデータメンバは、クラスまたは構造体のインスタンスが作成されるたびに、彼ら が宣言された順に連続して保存されています。クラスまたは構造にデータを整理するためのパフォーマンスペナルティはありません。 クラスまたは構造体オブジェクトのデータ にアクセスすると、単純な変数にアクセスする以上の時間がかかりません。 ほとんどのコンパイラは、あなたはいくつかのケースでサイズを縮小、パディングが追加された場合、その情報に基づいて並べ替えを通知するGCCの-Wpaddedを使用することができますアクセス

4

を最適化するために、アドレスを丸めるためにデータメンバーを揃えます。

データを強制的にパックすることは、メモリ内の表現には適していません。

0

親指の規則:最大から最小;要素サイズが2の累乗である場合には完全なアライメントが得られます。そうしないと、手動最適化が可能になります。

CPUが違反から回復した場合でも、通常は速度のために適切な調整が不可欠であることに注意してください。 x86と(AFAIK)x64 CPUの手の間では、2回目の読み取りで内部的にアクセスのミスアライメントが行われていましたが、ミスアライメントの読み込みにかかる時間は通常、作業セットが小さいために保存された時間よりもはるかに長くなります。だから私はあなたが複数のCPUの上で比較を実行するときにのみ "しっかりとパック"します。

非PODの場合は、sizeof(element)を確認する必要があります。
(オブジェクトのトンがある場合、私はおそらくこれらのサイズをダンプするためにC++を生成する簡単なパーサで行くと思います)

また、PVS-Studioは、構造体のサイズの分析を持っており、並べ替えの提案を提供します。私はまだそれらを考慮していませんが、それがあなたのために働いているかどうかを確認するために評価を使用することができます。

+0

メンバを並べ替えるのは簡単なオプションではありません。なぜなら、多くのエンコーダ/デコーダと、常に大きな頭痛のある他のRPCがあるからです。また、IOバウンドアプリケーションでは、CPUのパフォーマンスは重要ではありません。私は、このタイプのIOバウンドアプリケーションに特化した、ゲイン性能やルーズメモリよりもCPUを詰め込んでゆっくりと実装したいと思っています。 – dbbd

0

非PODオブジェクトに関して、vTable、仮想関数、仮想継承の詳細を読んで、どのオブジェクトがクラスまたはオブジェクトのサイズを実行しているかを知る必要があります。実際には、詰め物を詰めるクラスの整列、クラスメンバの整列だけがファクタのサイズを実行します。

ここにいくつかの関連ウェブサイトがありますが、私はあなたに役立つと思います。

  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 
関連する問題