ABI (System V など) と C++ 標準の違いを理解しようとしています。したがって、C++ 標準は、コンパイラがこれを適切なアセンブリ コードに変換できるように、正当な C++ を決定するだけです。ABI は、このアセンブリ コードが x86 アーキテクチャとどのように相互作用するかを規制しますか? それは両者のより高いレベルの比較ですか?
質問する理由は、低レイテンシのソフトウェアに興味があるため、ABI を読み取ることでどれだけの価値が得られるのだろうか?
標準は、作成したコードに基づいてプログラムが何をすべきかを定義します。ABI は、異なる実行で (おそらく異なるコンパイラ/バージョンによって) コンパイルされたコードが相互作用できるように、特定のプラットフォームに対してそれがどのように実装されるかを定義します。
つまり、次のように記述します。
void f(int i) { std::cout << i; }
標準では動作が定義されています。その関数を呼び出すと、引数の値が出力されます。ABI は、関数を呼び出すことができるようにアセンブリを生成する方法を決定します (f
マングルの名前はどうですか?) 引数を渡すことができます (引数はスタックのどこかにあるのでしょうか? レジスターの中にありますか?)。
質問の大胆な部分については…まあ、場合によります。ABI は読み取りが重いため、読んで理解するのは困難です。ただし、少なくとも、呼び出し規約などの基本事項のいくつかに精通している必要があります (タイプのオブジェクトを渡すコストはT
いくらですか?)...それを超えて、私はそれをリアクティブなアプローチにします: プロファイルと、何を理解する必要があるか進行中の場合、ABI が役立つ可能性があります。
ほとんどのプログラマーは自分のプラットフォームの ABI を知りませんが、同じように幸せに暮らしています。特に、プログラムの動作の特殊性を理解するために、何度か行ったり来たりしました。
直接の質問について: ABI を理解すると、ある程度は役に立ちます。しかし、ABI は、特定の C++ アプリケーションで何が効率的であるか (たとえば、インライン化を使用した場合の効果など) を教えてくれるわけではありません。同様に、vector
C スタイルの配列と比較して使用するという選択は、場合によっては利点をもたらすかもしれませんが、他の場所ではほとんど違いがないため、一方から他方へ変更する価値はありません。
低レイテンシのソフトウェアは、ABI の 13.6.2 段落が VTABLE の編成方法について正確に知ることよりも、コンパイラが特定のコードで一般的に何をするかを理解することです。コンパイルは VTABLE レイアウトの影響を直接受けます - ほとんどの場合、それは問題ではありません (仮想関数は間接呼び出しであり、対応する直接呼び出しよりも少し遅くなる可能性があり、単純な関数の場合は大幅に遅くなるということを理解した上で)関数のインライン バージョンよりも。
「引数を渡すために使用されるレジスタの数」などは確かに気にしますが、コンパイラが引数を渡すための 3 つのレジスタとして R0、R1、R2、または R13、R14、および R15 を使用するかどうかを知ることはそれほど重要ではありません。
そして最も重要なことは、コンパイラが何をするかをどれだけ理解していると思っていても、アセンブラの出力を見たり、プロファイラを介してコードを実行したりすることで、ABI 仕様を読むよりもはるかに多くのことを知ることができるということです。通常のコードでは、時間の 90% がコードの 10% に費やされることに注意してください。合計実行時間の 0.001% を使用する関数の「遅さ」を修正することは、おそらく無駄な作業です。