用asm代码在C++中交换2个变量

Interchange 2 variables in C++ with asm code

本文关键字:交换 2个 变量 C++ asm 代码      更新时间:2023-10-16

我有一个巨大的函数,可以对大量的int数据进行排序。代码运行良好,只是速度比应该的慢。解决这个问题的第一步是在C++中放置一些asm代码。如何使用asm交换2个变量?我试过这个:

_asm{ push a[x]; push a[y]; pop a[x]; pop a[y];}

这个:

_asm(mov eax, a[x];mov ebx,a[y]; mov a[x],ebx; mov a[y],eax;}

但两者都崩溃了。我怎样才能在这些立交桥上节省一些时间?我使用VS_2010

通常,使用这样的简单代码很难比编译器做得更好。

编译器在面对整数的交换操作时,通常会发出这样的代码:

mov eax, [x]
mov ebx, [y]
mov [x], ebx
mov [y], eax

在尝试重写之前,首先检查编译器实际生成的内容。如果是这样的事情,不要再麻烦了;你再也做不到比这更好的了。此外,如果您将其留给编译器,那么如果此后立即使用这些变量,它可能会选择重用其中一个寄存器来保存变量加载/存储。这对于手工编码的装配是不可能的;编译器必须在手工编码asm的黑框之后重新加载变量。

请注意,推/推/弹出/弹出序列可能要慢得多;它不仅向堆栈添加了额外的四个内存操作,还引入了对堆栈指针的依赖,消除了任何流水线操作的可能性。使用简单的mov序列,如果读对和写对位于不同的内存组上,或者其中一个位于缓存中,则至少可以并行运行它们。它也不会在以后的代码中在堆栈指针上引入暂停。

因此,您不应该试图对交换的成本进行微观优化;相反,减少执行的交换次数。有许多可用的排序算法,每种算法的特征都略有不同。您可能会发现有些数据集比其他数据集更好(因为交换更少)。

是什么让你认为你可以产生比优化编译器更快的汇编
即使你能让它正常工作,你可能要做的就是混淆优化器,产生更慢的代码。

当您进行内联汇编时,您可以进行更改,以便编译器对寄存器内容所做的假设不再为真。通常情况下,EAX用于传递参数或返回值,因此破坏EAX可能没有多大效果,但您破坏了EBX,没有将其放回,这可能会导致问题。在你使用EBX之前试着推它,然后在你用完后弹出它。

您可以将汇编代码中的变量名、函数名和标签用作符号。注意,像a[x]这样的东西并不是这样有效的符号。

编写更高效的代码需要技巧和知识,使用asm不一定能帮助你。

您可以将编译器为函数生成的汇编代码与内联汇编程序和不使用内联汇编程序进行比较,以查看您在哪里破坏了它