ページへ戻る
印刷
技術系備忘録/C++/最適化小手先テクニック/メンバ変数の並びを考慮すべし
をテンプレートにして作成 ::
シンクリッジ
xpwiki
:技術系備忘録/C++/最適化小手先テクニック/メンバ変数の並びを考慮すべし をテンプレートにして作成
開始行:
クラス(や構造体)のメンバ変数の並びによって、クラスのメ...
-List1
#prettify{{
class CClass{
public:
char m_nCharA;
int m_nIntA;
char m_nCharB;
int m_nIntB;
};
}}
クラス CClass のメモリサイズは、16バイトです。
メンバ変数は、char が2つ、int が2つのなので、実際に使用...
アラインされて16バイトになってしまっています。
これを避けてメモリ節約をする場合、リスト2のようにします。
-List2
#prettify{{
class CClass{
public:
int m_nIntA;
int m_nIntB;
char m_nCharA;
char m_nCharB;
};
}}
こうすることでクラス CClass のメモリサイズは、12バイトに...
しかしそれでも 2バイト余分なものが入っています。
ここまでで十分だと思うのですが、さらにこの2バイトを節約...
-List3
#prettify{{
#pragma pack( push )
#pragma pack( 1 )
class CClass{
public:
int m_nIntA;
int m_nIntB;
char m_nCharA;
char m_nCharB;
};
#pragma pack( pop )
}}
これで 10バイトに収まりました。
#pragma pack でアラインサイズを1バイトに変えてしまうこと...
もちろん、リスト1のままでも #pragma pack をしてしまえば...
コンパイラがアラインを行うのは、プロセッサのメモリアクセ...
サイズ縮小によるメモリ節約というメリットと、区切りの悪い...
というわけですが、まず言えることは、メンバ変数を定義する...
int long は4バイト境界。
short は2バイト境界。
char bool は1バイトなのでどこでもOK。
** ご指摘いただきました。ありがとうございます。(2005/4/7...
-念のため匿名さん
> sizeof bool は実装依存なので 1 ではない事があるよ。
ごもっともです。説明が足りませんでした。すみません。
今の言語規格では、bool以外にも char 以外の全ての型の実サ...
ですので、ここに紹介してあるサイズが全ての処理系で正しい...
** ご指摘いただきました。ありがとうございます。(2005/4/7...
-念のため匿名さん
>> メンバ変数の並びを考慮すべし
> これは初期化される順番を先に考慮すべきだと思います。
これは、メンバ変数の初期化順序に依存関係がある場合におい...
との事です。最初は何のことか分かりませんでした。猛省。
たとえば、以下のようなクラスは、メモリ節約を無視してでも...
(少々強引なコードですが、良い例が思いつかない・・・。)
-
#prettify{{
class CClass{
public:
short m_count; // 初期化リストは、メンバの定義順に処理さ...
int m_size1; // この順序を崩すと、期待通りの値にならな...
short m_size2; // この場合はパディング覚悟でこの順序にす...
CClass(int nCount)
:m_count(nCount)
,m_size1(m_count * sizeof(int))
,m_size2(m_size1 * sizeof(int))
{}
};
}}
なお、これは初期化リストの処理順序の話なので、初期化リス...
がしかし初期化リストに書くことによるメリットもあると思う...
終了行:
クラス(や構造体)のメンバ変数の並びによって、クラスのメ...
-List1
#prettify{{
class CClass{
public:
char m_nCharA;
int m_nIntA;
char m_nCharB;
int m_nIntB;
};
}}
クラス CClass のメモリサイズは、16バイトです。
メンバ変数は、char が2つ、int が2つのなので、実際に使用...
アラインされて16バイトになってしまっています。
これを避けてメモリ節約をする場合、リスト2のようにします。
-List2
#prettify{{
class CClass{
public:
int m_nIntA;
int m_nIntB;
char m_nCharA;
char m_nCharB;
};
}}
こうすることでクラス CClass のメモリサイズは、12バイトに...
しかしそれでも 2バイト余分なものが入っています。
ここまでで十分だと思うのですが、さらにこの2バイトを節約...
-List3
#prettify{{
#pragma pack( push )
#pragma pack( 1 )
class CClass{
public:
int m_nIntA;
int m_nIntB;
char m_nCharA;
char m_nCharB;
};
#pragma pack( pop )
}}
これで 10バイトに収まりました。
#pragma pack でアラインサイズを1バイトに変えてしまうこと...
もちろん、リスト1のままでも #pragma pack をしてしまえば...
コンパイラがアラインを行うのは、プロセッサのメモリアクセ...
サイズ縮小によるメモリ節約というメリットと、区切りの悪い...
というわけですが、まず言えることは、メンバ変数を定義する...
int long は4バイト境界。
short は2バイト境界。
char bool は1バイトなのでどこでもOK。
** ご指摘いただきました。ありがとうございます。(2005/4/7...
-念のため匿名さん
> sizeof bool は実装依存なので 1 ではない事があるよ。
ごもっともです。説明が足りませんでした。すみません。
今の言語規格では、bool以外にも char 以外の全ての型の実サ...
ですので、ここに紹介してあるサイズが全ての処理系で正しい...
** ご指摘いただきました。ありがとうございます。(2005/4/7...
-念のため匿名さん
>> メンバ変数の並びを考慮すべし
> これは初期化される順番を先に考慮すべきだと思います。
これは、メンバ変数の初期化順序に依存関係がある場合におい...
との事です。最初は何のことか分かりませんでした。猛省。
たとえば、以下のようなクラスは、メモリ節約を無視してでも...
(少々強引なコードですが、良い例が思いつかない・・・。)
-
#prettify{{
class CClass{
public:
short m_count; // 初期化リストは、メンバの定義順に処理さ...
int m_size1; // この順序を崩すと、期待通りの値にならな...
short m_size2; // この場合はパディング覚悟でこの順序にす...
CClass(int nCount)
:m_count(nCount)
,m_size1(m_count * sizeof(int))
,m_size2(m_size1 * sizeof(int))
{}
};
}}
なお、これは初期化リストの処理順序の話なので、初期化リス...
がしかし初期化リストに書くことによるメリットもあると思う...
ページ名: