1

MSVC で x64 アセンブリを学習しています。x64 コードでは、インライン アセンブリは許可されていません。別のファイルに非常に単純な浮動小数点関数を書きました。

.data
TWO_DOUBLE real8 2.0

.code
mul2 proc
    movsd xmm1, TWO_DOUBLE
    mulsd xmm0, xmm1
    ret 
mul2 endp

次に、C++ から関数を呼び出しました。

extern "C" double mul2(double x);

int main()
{
    double d2 = mul2(1.0);
}

リリース モードでコンパイルし、/O2最適化して/LTCG有効にすると、逆アセンブルされた実行可能ファイルは次のようになります。

<addr> movsd  xmm0, mmword ptr [__real@3ff0000000000000 (013F9F21A8h)]  
<addr> call   mul2 (013F9F1075h)

ただし、同じ関数を C++ で記述すると、単一のインラインmulsd命令に変換されます。

(実際には、プログラム全体がノーオペレーションにならないように から結果を返さなければならmainず、入力変数をランダム化して、コンパイル時にコンパイラが結果を計算しないようにする必要がありました。)

これは、手書きのアセンブリでコードを最適化したいプログラマーにとって、かなり深刻な欠陥のように思えます。MSVC がそれをインライン化できない場合、アセンブリで大量の作業を行わない限り、関数呼び出しのオーバーヘッドに見合わない可能性があります。

不足している手書きのアセンブリを MSVC でインライン化する方法はありますか?

編集:スタックを使用するより複雑なアセンブリ関数はインライン化がより困難になる可能性があることは承知していますが、揮発性レジスタのみを使用する単純なものは本当に簡単なはずです...そうですか?

4

1 に答える 1

3

WPO (プログラム全体の最適化) でクロスモジュールのインライン化を適用するには、呼び出しモジュールと呼び出されたモジュールの両方を .xml でコンパイルする必要があります/LTGC

/LTGC最終的なバイナリ コードではなく、中間言語 (CIL) を含む特殊なオブジェクト ファイルを生成します。アセンブリは既にマシン コードであるため、WPO に参加できず、インライン化できません。

SIMD 命令を使用しながらも WPO を利用したい場合は、アセンブリの代わりにコンパイラ組み込み関数を使用できます。たとえば、 にmulsd対応し_mm_mul_sdます。

于 2014-08-26T18:03:18.183 に答える