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

问题描述 投票:5回答:6

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

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

据我所知:

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

问题:

  • 我不知道从哪里开始。在我的内联汇编发挥作用时,哪个寄存器是什么?
c++ visual-studio-2010 visual-c++ inline-assembly micro-optimization
6个回答
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可能对你也很有趣。


8
投票

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

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

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


6
投票

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

__asm {
  mov eax, [a]
}

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

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


3
投票

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

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

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

这些是我的建议,你的里程可能会变化(YMMV)。


1
投票

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

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

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


1
投票

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.