3

パッキングによるオブジェクトファイルのオーバーヘッドをカウント/合計したい(そして、理想的には、gccに最小化させたい)。

たとえば、次の構造(32ビットx86、gcc)について考えてみます。

struct a { 
    uint8_t a_char;
    uint32_t an_integer
    uint8_t another_letter;
};

実際のデータは6バイトしか使用しませんが、両方の文字の後に3つのパディングバイトが続くため、構造体はメモリ内で12バイトを使用します。次のように構造を並べ替えることによって:

struct b { 
    uint32_t an_integer
    uint8_t a_char;
    uint8_t another_letter;
};

構造体のsizeof(struct b)== 8のみになります(まだ4バイトのオーバーヘッド)。

(1)理想的には、gccを再配置struct astruct bてスペースを節約したいのですが、私のバージョン(4.2)は、どの最適化レベルでもこれを実行していないようです。

(2)または、与えられた場合、数(オーバーヘッドの合計量)または(メンバーが「理想的に」注文されている場合はオーバーヘッドの最小量)のstruct aいずれかを(自動的に)取得したいと思います。これの目的は、構造を手動で並べ替える価値があるかどうかを判断することです(おそらくそうではありません)。64

gccが(1)を実行する方法はありますか?また、(2)を実行するツールはありますか?(1)について私が考えることができる最も近いことは#pragma pack(1)ですが、(私が推測しているように)ほとんど/すべてのメモリアクセスを非整列にすることにより、パフォーマンスに深刻な影響を及ぼします。(2)の場合、デバッグシンボルを解析するPerlスクリプトでこれを実行できる可能性があると思いますが、DWARFに精通していないため確実に知ることができません。

4

3 に答える 3

8

#1の場合、これが行われない理由は、C標準とC++標準の両方で構造体メンバーの並べ替えが禁止されているためです。

はい、構造体パッキングは一般的にパフォーマンスを低下させます。また、コメントで述べたように、x86以外のアーキテクチャでは、メンバーを操作しようとするとSIGBUSを取得できる場合があります。

#2の場合、はい、perlスクリプトで実行できる可能性があります。DWARF情報を解析する代わりに、構造体定義のソースコードをスキャンしてみたり、構造体やメンバーのsizeof()などをチェックするための小さなテストプログラムを生成したりすることができます。

于 2011-07-12T07:05:30.253 に答える
3

Linuxには、paholeと呼ばれるツールがあり、デバッグ情報を含むELFファイルを解析し、各構造体の各メンバーの配置とコンパイラによって行われるパディングの量を出力します。オーバーヘッドが多すぎることに気付いた場合は、その情報を使用して手動で梱包するようにガイドできます。

于 2011-07-12T07:42:24.977 に答える
0

これは常に実行できるとは限りません。問題は、すべてのアーキテクチャでアラインされていないメモリへのアクセスが許可されていないことです。これにより、コンパイラのコードが簡素化され、メモリ自体への特定のアクセスを最適化できるようになります。また、非常にメモリに敏感なソフトウェアを実行していない限り、構造ごとに4〜8バイトのオーバーヘッドは大した問題ではないため、構造を再編成することはおそらく時間の価値がありません。あなたの質問に関しては、方法があるかどうかはわかりませんが、誰かがあなたに知らせてくれることを知っているかどうかはわかります(おそらく、最適化フラグが最も高いgcc-4.6がそれを行いますか?)

于 2011-07-12T07:04:22.623 に答える