コードの高速化: AMD64で16バイトを超える構造体を渡してはいけない
- Neat言語の性能向上のため、配列を1つの構造体パラメータとして渡す代わりに、3つのポインタパラメータとして渡す方式に変更した。
- Neatの配列がD言語の配列より遅かった理由は、24バイトの配列サイズが16バイトを超えており、その結果パラメータの渡し方が異なるためだった。
- SystemV AMD64 ABI仕様によれば、16バイトを超えるすべての構造体はポインタ経由で渡される。
ベンチマークによる問題の確認
- ベンチマークを通じて、構造体を渡す方式と個別のフィールドを渡す方式の性能差を確認した。
- 構造体を渡す場合はスタックへの割り当てとコピーの過程が必要だが、個別のフィールドを渡す場合はSSEレジスタを通じてそのまま渡される。
- 個別のフィールドを渡す方式は、構造体を渡す方式と比べて約2倍高速だった。
言語設計者の選択
- C APIを呼び出す際にはC ABIに従う必要があるが、内部で使われる高級型を構造体として表現する必要はない。
- 言語設計者は、配列、タプル、和型などがどのように渡されるかを決めることができる。
- 16バイトを超える型を個別のフィールドとして渡すことは、性能向上に役立つ可能性がある。
GN⁺の意見
- この記事は、ソフトウェア最適化に関心のある開発者にとって非常に有益だ。
- 特に、性能に敏感なアプリケーションを開発する際に、構造体のサイズと受け渡し方法が重要な影響を与えうることを示している。
- 言語設計者やAPI開発者は、この情報を活用して性能を改善できる機会を得られる。
1件のコメント
Hacker Newsのコメント