明显操作的复杂代码

rke*_*erm 1 c++ optimization inline-assembly

有时,主要出于优化目的,非常简单的操作被实现为复杂和笨拙的代码.

一个例子是这个整数初始化函数:

void assign( int* arg )
{
    __asm__ __volatile__ ( "mov %%eax, %0" : "=m" (*arg));
}
Run Code Online (Sandbox Code Playgroud)

然后:

int a;
assign ( &a );
Run Code Online (Sandbox Code Playgroud)

但实际上我不明白为什么用这种方式写的......

你有没有看到任何有真正理由的例子?

Joh*_*nFx 21

在你的例子的情况下,我认为这是错误的假设的结果,即在汇编中编写代码会自动更快.

问题在于写这篇文章的人并不明白为什么汇编有时可以更快地运行.也就是说,您比编译器更了解您正在尝试做什么,并且有时可以使用这些知识在较低级别编写代码,而不必根据编译器的假设进行编译.

在简单的变量赋值的情况下,我严重怀疑它是否成立并且代码可能执行得更慢,因为它具有管理堆栈上的assign函数的额外开销.请注意,它不会明显变慢,这里的主要成本是代码,其可读性和可维护性较差.

这是一个教科书示例,说明为什么在不理解为何是优化的情况下不应实现优化.

  • 良好的整体写入,但缺少asm的最重要的用途 - 使用C++没有表达的CPU指令.没有指令在C++中进行高度并行操作,也没有原子操作,内存缓存控制等.除非你正在编写一个令人难以置信的高性能程序(例如笔记本电脑的实时高清视频,实时衍生品定价),否则它只是您可能会使用其他无法访问的指令,如果您很幸运,环境中的大部分功能都可以在非标准支持头中使用. (6认同)

Rin*_*g Ø 8

似乎汇编代码意图是确保*arg每次都完成对int位置的赋值- 在这方面阻止(故意)编译器的任何优化.

通常,在C++(和C ...)中使用volatile关键字来告诉编译器这个值不应该保存在寄存器中(例如)并从该寄存器中重用(优化以便更快地获得值),因为它可以异步更改(通过外部模块,汇编程序,中断等...).

例如,在一个函数中

  int a = 36;
  g(a);
  a = 21;
  f(a);
Run Code Online (Sandbox Code Playgroud)

在这种情况下,编译器知道该变量a是函数的本地变量,并且不在函数外部进行修改(例如,a没有向任何调用提供指针).它可以使用处理器寄存器来存储和使用a变量.

总之,ASM指令似乎被注入到C++代码中,以便对该变量执行某些优化.

  • 好的一点 - 通常你会在代码中找到用来解决缺少的语言能力(或者在编译器中缺失)的东西,这些东西已经被纠正了.根据@ rursw1正在查看的代码的年龄,这可能是发生的事情. (2认同)