我正在编写一个性能关键,数字运算的C ++项目,其中70%的时间被200线核心模块使用。
我想使用内联汇编来优化内核,但我对此完全陌生。但是,我知道一些x86汇编语言,包括GCC和NASM使用的语言。
我所知道的全部:
我必须将汇编程序指令放在_asm{}
我想要的位置。
问题:
答案 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文档有关,这个文档非常简洁,但仍然是一个合理的开端。