如何:使用C ++内联汇编程序(在Visual Studio 2010下)

时间:2010-05-15 10:14:35

标签: c++ visual-studio-2010 visual-c++ inline-assembly micro-optimization

我正在编写一个性能关键,数字运算的C ++项目,其中70%的时间被200线核心模块使用。

我想使用内联汇编来优化内核,但我对此完全陌生。但是,我知道一些x86汇编语言,包括GCC和NASM使用的语言。

我所知道的全部:

我必须将汇编程序指令放在_asm{}我想要的位置。

问题:

  • 我不知道从哪里开始。目前我的内联汇编发挥作用的是什么?

6 个答案:

答案 0 :(得分:13)

您可以按名称访问变量并将其复制到寄存器。 以下是MSDN的一个例子:

int power2( int num, int power )
{
   __asm
   {
      mov eax, num    ; Get first argument
      mov ecx, power  ; Get second argument
      shl eax, cl     ; EAX = EAX * ( 2 to the power of CL )
   }
   // Return with result in EAX
}

Using C or C++ in ASM blocks对你来说可能也很有趣。

答案 1 :(得分:8)

当涉及内联汇编时,微软编译器在优化方面非常差。它必须备份寄存器,因为如果你使用eax,那么它不会将eax移动到另一个空闲寄存器,它将继续使用eax。 GCC汇编程序在这方面要先进得多。

为了解决这个问题,微软开始提供intrinsics。这些是更好的优化方法,因为它允许编译器与您合作。正如Chris提到的内联汇编在x64下使用MS编译器也不行,所以在那个平台上,你最好只使用内在函数。

它们易于使用且性能良好。我承认我经常能够通过使用外部汇编程序来挤出更多的循环,但它们对于提高生产率而言非常有利于

答案 2 :(得分:6)

寄存器中没有任何内容。当_asm块被执行。你需要将东西移入寄存器。如果有一个变量:'a',那么你需要

__asm {
  mov eax, [a]
}

值得指出的是,VS2010配备了Microsofts汇编程序。右键单击项目,转到构建规则并打开汇编程序构建规则,然后IDE将处理.asm文件。

这是一个更好的解决方案,因为VS2010支持32位和64位项目,而__asm关键字不适用于64位版本。您必须使用外部汇编程序64位代码:/

答案 3 :(得分:3)

我更喜欢在汇编中编写整个函数,而不是使用inline汇编。这允许您在构建过程中将高级语言函数替换为程序集。此外,您不必担心编译器优化会妨碍您。

在编写单行程序集之前,请打印出函数的汇编语言列表。这为您提供了构建或修改的基础。另一个有用的工具是将汇编与源代码交织在一起。这将告诉您编译器如何编写特定语句。

如果需要为大型函数插入内联汇编,请为需要内联的代码创建一个新函数。在构建期间再次使用C ++或程序集替换。

这些是我的建议,你的里程可能会有所不同(YMMV)。

答案 4 :(得分:1)

首先去寻找低悬的果实......

正如其他人所说,Microsoft编译器在优化方面相当差。您可以通过投资合适的编译器(例如Intel的ICC)并“按原样”重新编译代码来节省大量精力。您可以从英特尔获得30天免费评估许可证并进行试用。

此外,如果您可以选择构建64位可执行文件,那么由于可用寄存器数量增加了x2,因此以64位模式运行可以使性能提高30%。

答案 5 :(得分:1)

我真的很喜欢集会,所以我不会在这里成为一个不言而喻的人。您似乎已经分析了代码并找到了“热点”,这是正确的启动方式。我还假设有问题的200行不使用像vector这样的大量高级结构。

我必须给出一点警告:如果数字运算涉及浮点数学运算,那么你就是一个痛苦的世界,特别是一整套specialized instructions,以及一个大学术语的价值algorithmic study

所有这一切:如果我是你,我会使用反汇编视图在VS调试器中单步执行相关代码。如果您在阅读代码时感觉很舒服,这是一个好兆头。之后,执行Release compile(Debug关闭优化)并为该模块生成ASM列表。 然后如果你认为你有改进的余地......你有一个可以开始的地方。其他人的答案与MSDN文档有关,这个文档非常简洁,但仍然是一个合理的开端。