Pebble's Diary

プログラマーの作業メモ

C/C++ 構造体アライメント最適化

C/C++の構造体の要素はある程度の境界位置にアライメントされる。そのため、要素の定義順序によって、構造体全体のサイズが変わったりする。たかが数バイトと侮るなかれ。要素数が多ければ、それだけメモリ領域が小さくなり、CPUキャッシュミスが起きる確率が下がり、高速化が望めるのだ。

struct Info1 {
    uint8_t dex;      // 1byte
    int64_t strength; // 8byte 
    float vital;      // 4byte
};

struct Info2 {
    uint8_t dex;      // 1byte
    float vital;      // 4byte
    int64_t strength; // 8byte 
};

printf("sizeof(Info1) %d dex %d:%d strength %d:%d vital %d:%d\n",
           sizeof(Info1), 
           offsetof(Info1, dex), sizeof(Info1::dex),
           offsetof(Info1, strength), sizeof(Info1::strength),
           offsetof(Info1, vital), sizeof(Info1::vital));
           
printf("sizeof(Info2) %d dex %d:%d vital %d:%d strength %d:%d\n",
           sizeof(Info2), 
           offsetof(Info2, dex), sizeof(Info2::dex),
           offsetof(Info2, vital), sizeof(Info2::vital),
           offsetof(Info2, strength), sizeof(Info2::strength));
sizeof(Info1) 24 dex 0:1 strength 8:8 vital 16:4
sizeof(Info2) 16 dex 0:1 vital 4:4 strength 8:8

上記サンプルでは構造体Info1,Info2の違いはvitalとstrengthの定義位置を逆にしただけなのだが、なんと構造体サイズが8バイトも節約できてしまった。このように、大量にインスタンスを生成する構造体においてはアライメントを考慮した上で要素数の定義順を変えるとよい。