用asm代码在C++中交换2个变量
Interchange 2 variables in C++ with asm code
我有一个巨大的函数,可以对大量的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不一定能帮助你。
您可以将编译器为函数生成的汇编代码与内联汇编程序和不使用内联汇编程序进行比较,以查看您在哪里破坏了它
- 使用 std::vector::swap 方法在C++中交换两个不同的向量是否安全?
- 在 CPP 中交换 2 个数字
- 交换N个变量
- 交换两个字符串时访问正确的内存时,我遇到了分段错误
- 如何在单个链表中交换两个节点的位置,只修改指针
- 如果静态变量只为程序的整个部分存储了一个副本,为什么我不能使用静态变量交换 2 个数字?
- 是否可以在C++中使用宏交换两个变量的出现?
- 如何以通用方式交换两个值
- 为什么不交换两个节点?
- 使用用户函数在 C++ 中交换两个结构
- 编写一个功能,该函数将使用框架交换两个整数
- 如何在没有复制赋值运算符的情况下交换两个对象
- 如何在多线程 c++ 17 程序中交换两个指针
- 尝试使用 {} 和 std::make_pair() 交换两个变量时的行为不同
- C :交换两个不同向量的两个元素
- 在Variadic模板中交换两个参数
- C 交换两个void*的内容
- 交换两个类实例的最安全方法
- 为什么基于指针交换两个值在函数范围之外不起作用?
- 交换两个 std::array<T、100> 对象的成本是多少?