我在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内联手写的程序集丢失?
编辑:我意识到使用堆栈的更复杂的汇编函数可能更难以内联,但是只使用易失性寄存器的简单操作应该非常简单......对吗?
答案 0 :(得分:2)
对于要应用跨模块内联的WPO(整个程序优化),两者必须使用/LTGC
编译调用和调用的模块。
/LTGC
不产生最终的二进制代码,而是产生中间语言(CIL)的特殊目标文件。由于您的程序集已经是机器代码,因此它无法参与WPO,因此无法内联。
如果您想使用SIMD指令但仍然可以利用WPO,则可以使用compiler intrinsics而不是汇编。例如,mulsd
对应_mm_mul_sd
。