ホームページ > バックエンド開発 > Golang > C 構造体のレイアウトの最適化

C 構造体のレイアウトの最適化

DDD
リリース: 2025-01-03 13:57:39
オリジナル
989 人が閲覧しました

簡単な C 構造体を考えてみましょう:

struct foo {
    const char * str;
    unsigned char flag;
    uint64_t len;
};
ログイン後にコピー
ログイン後にコピー

このコードが 64 ビット マシンで実行されるプログラムの一部として実行されていると仮定します。sizeof(struct foo) の結果はどうなるでしょうか?

構造体のサイズや最適化をいじる必要がなかったほとんどの人は、それが 17 であるべきだと推測するでしょう...

...でも もう 24 時です!それはなぜですか?

この動作の理由は、コンパイラが速度向上のために構造体のレイアウトを最適化しており、整列されたメモリ アクセスがデータにアクセスする最速の方法であるという現代の標準であるためです。

これは、フィールドと CPU のタイプに応じて、データに何らかのアライメントがあり、そのアライメントが尊重されるように (または、field-address % field-alignment == 0 になるように) 配置されることを意味します。

サイズ、配置、パディング

前の例の場合、ポインタと 64 ビット フィールドは 64 ビット マシン上で 8B にアライメントされています。これは、構造体のすべてがアライメントされるレイアウトを強制するために、コンパイラがいくつかのflag フィールドと len フィールドの間のパディング:

optimizing c structs layouts

次に、前と同じマシン上で次のような構造体が定義されている別の例を考えてみましょう。

struct bar {
    const char * str;
    short s1;
    int i1
    short s2;
    int i2;
};
ログイン後にコピー
ログイン後にコピー

そのサイズを計算するにはどうすればよいですか?

3 つのルールがあります:

  • 構造体フィールドは、独自の自然な配置に合わせて配置する必要があります。
  • 構造体全体のアライメントは、その最も広いフィールドのアライメントと同じです
  • 同じ型の 2 つの構造体を並べて配置する必要がある場合、2 番目の構造体はその配置に合わせて配置する必要があります。これは、構造体にはその配置まで末尾のパディングが必要であることを意味します

64 ビット マシンの基本的な型の配置とサイズの簡単な要約:

type size alignment
char 1 1
short 2 2
int 4 4
long 8 8
float 4 4
double 8 8
pointers 8 8

次の点にも注意してください:

  • 配列には値の型とサイズ (sizeof(type) * 要素数) のアラインメントがあります。
  • 共用体には、最も広いメンバーの位置合わせとサイズがあります。

また、非常に便利な sizeof 演算子と _Alignof 演算子を使用して、カスタム タイプの情報を取得できます。 _Alignof は C11 以降で使用可能であり、C23 以降は alignof と呼ばれることに注意してください。 C 11 以降、私が C で理解していることによれば、それは常に alignof でした。

詳細については、このトピックのバイブルは『The Lost Art of Structure Packing』です。私はこの本について、私が知っているほぼすべてのことを、多くの実践と実践経験とともに学びました。

構造体の最適化: stropt

ここでのこのトピックは、職場でかなり頻繁に取り上げられるもので、大量のデータをキューなどで継続的に送信するときに、あちこちでバイトを節約することが非常に重要です。

作業を楽にするために、ソース ファイルまたはコード スニペットを参照して、入力として渡された型に関する統計を生成するツールを作成しました。stropt (構造体オプティマイザー).

Abathargh/stropt on GitHub

構築とインストール

ローカルに go がインストールされている場合は、すぐに進んでアプリケーションを直接ビルドまたはインストールできます。

struct foo {
    const char * str;
    unsigned char flag;
    uint64_t len;
};
ログイン後にコピー
ログイン後にコピー

OS/アーキテクチャの組み合わせのリスト用にコンパイル済みのバイナリも、github リリース ページで提供されています。

stropt バイナリ

ツールを使って

分析するソースを文字列として渡すことで、stropt を使用できます。

struct bar {
    const char * str;
    short s1;
    int i1
    short s2;
    int i2;
};
ログイン後にコピー
ログイン後にコピー

optimizing c structs layouts

または、定義が含まれるファイルを渡すこともできます:

git clone https://github.com/Abathargh/stropt
go build

// or, if you want to install this directly
go install github.com/Abathargh/stropt
ログイン後にコピー

optimizing c structs layouts

このツールは、-optimize フラグを使用して型の最適化を行うこともでき、構造体自体であるフィールドを認識します。

optimizing c structs layouts

冗長フラグは、内部構造体 (および共用体) をフィールドの配置とサイズとともに表示するために使用されることに注意してください。

次は何ですか

このツールは、C コードの解析に優れた modernc.org/cc C コンパイラー フロントエンドを使用し、UI に Charmbracelet のリップグロスを使用して Go で作成されました。

これは自分用に書いていますが、喜んで公開します。これをブラウザで直接簡単に使えるように Web アプリにしたいので、おそらく次の作業はこれになると思います!

以上がC 構造体のレイアウトの最適化の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート