2

命令の再スケジューリング後にコンパイラが生成するのと同じ順序で逆アセンブルされたコードを確認したいと考えています。ところで、私はGDBを使用してdisas /m FunctionNameいます。コマンドを実行すると、ソースコードの順序で逆アセンブルされたコードが表示されます。コンパイラ (GCC 4.1) による命令の再スケジュールの有効性を調べようとしており、命令がどのように再スケジュールされるかを確認したいと考えています。ありがとう!//////////////////編集///////////////////////////// ///////// コード行の逆アセンブル コードを見た後:

double w_n =  (A_n[2] * x[0] + A_n[5] * y + A_n[8] * z + A_n[11])  ;

83バイトの命令を見ることができました。しかし、2回の反復で展開した後:

double w_n[2] = { (A_n[2] * x[0] + A_n[5] * y + A_n[8] * z + A_n[11]), (A_n_2[2] * x[0] + A_n_2[5] * y + A_n_2[8] * z + A_n_2[11]) };

コードのブロックは 226 バイトです。また、命令数が大幅に増加しています。なぜこれが起こっているのか誰か教えてもらえますか?VTune からも、展開後にリタイアした命令が増えていることがわかります。私が考えることができる考えられる理由: コンパイラーは、単純な命令を生成するためにブロックサイズを大きくして十分な機会を得て、命令のプリフェッチとデコーダーユニットのスループットを最大化します。

どんな助けでも大歓迎です。ありがとう!!

4

2 に答える 2

4

コードをオブジェクト ファイルにコンパイルするステップで、gccアセンブリ コードを取得することを GCC ドライバー ( ) に伝えることもできます。

gcc -S -c file.c
gcc -O2 -S -c file.c
gcc -S -masm=intel -c file.c

(後者は AT&T 構文アセンブリの代わりに Intel を生成します)

そのアセンブリ コードを後でアセンブラ (例: gasm) にスローして、リンク可能なオブジェクト ファイルを取得することもできます。


コードが大きくなる理由については、いくつかの理由があります。私たち人間がアセンブリを手動で最適化するために使用したヒューリスティックは、かなり長い間、もはや真実ではありません。大きな目標の 1 つはパイプライン処理であり、もう 1 つのベクトル化です。全体として、実行を高速化するために、可能な限り並列化し、(既に読み取られた) キャッシュからの無効化を可能な限り少なくする必要があります。

直感に反するように見えますが、これにより、より大きく、より高速なコードが作成される可能性があります。

于 2014-04-15T10:34:08.297 に答える