4

マシンコードのアライメントの原則を理解しようとしています。実行時にマシンコードを生成できるアセンブラー実装があります。すべての分岐先で 16 バイトのアラインメントを使用していますが、最適な選択ではないようです。アラインメントを削除すると、同じコードよりも高速に動作する場合があることに気付いたからです。キャッシュ ライン幅と関係があると思います。そのため、一部のコマンドがキャッシュ ラインによってカットされ、そのために CPU がストールします。そのため、ある場所に数バイトのアラインメントが挿入されると、キャッシュの境界線を越えてどこかに命令が移動します...

コード全体を処理し、CPU の仕様 (キャッシュ ライン幅、32/64 ビットなど) に従ってアラインメントを挿入できる自動アラインメント手順を実装したいと考えていました...

誰かがこの手順についていくつかのヒントを与えることができますか? 例として、ターゲット CPU は Intel Core i7 CPU 64 ビット プラットフォームである可能性があります。

ありがとうございました。

4

4 に答える 4

2

通常、段落(16バイト)の配置が最適です。ただし、一部の「ローカル」JMP命令がローカルではなくなる可能性があります(コードサイズの肥大化のため)。また、キャッシュされるコードが少なくなる可能性があります。コードの主要なセグメントのみを整列させ、すべての小さなサブルーチン/JMPセクションを整列させるわけではありません。

于 2011-03-07T14:24:17.213 に答える
1

前述のように、これは非常に複雑な領域です。アグナーフォグは訪れるのに良い場所のようです。複雑さについては、ここでトルビョルングランランドの「不変整数による除算の改善」に関する記事に出くわしました。彼が新しいアルゴリズムを説明するために使用するコードでは、最初の命令は-おそらく-メインラベルはnop-操作なしです解説によると、パフォーマンスが大幅に向上します。図に行きます。

于 2011-03-08T18:12:15.083 に答える
1

ただし、専門家ではありません...命令キャッシュに入らない場所への分岐は、命令のキャッシュライン全体を読み取ってパイプラインを満たすため、アライメントの恩恵を受けるはずです。そのステートメントを考えると、関数の最初の実行時に前方分岐が役立ちます。後方分岐 (たとえば、"for" および "while" ループ) は、分岐先と後続の命令が既にキャッシュに読み込まれているため、おそらくメリットはありません。Martins answer のリンクをたどってください。

于 2011-03-07T12:43:02.950 に答える