我记得在某处读到过,为了真正优化和加速代码的某些部分,程序员用汇编语言编写该部分.我的问题是-

  1. 这种做法还在做吗?如何做到这一点呢?
  2. 用汇编语言编写是不是有点太麻烦了&而且太过时了?
  3. 当我们编译C代码时(带或不带-O3标志),编译器进行一些代码优化&链接所有库&将代码转换为二进制目标文件.因此,当我们运行该程序时,它已经是其最基本的形式,即二进制.那么,归纳"汇编语言"有什么帮助呢?

我正在努力理解这个概念&任何帮助或链接都非常感谢.

UPDATE:按照dbmerlin的要求重新表述第3点-因为您可能能够编写比编译器生成的更有效的汇编代码,但是除非您是汇编专家,否则您的代码可能会运行得更慢,因为编译器通常比大多数人更好地优化代码.

推荐答案

恢复到汇编语言唯一有用的时候是

...AND...

  • 这些CPU指令的使用将给瓶颈代码带来一些显著而有用的性能提升.

简单地使用内联汇编来做一个操作,它可以很容易地用C++来表达,比如添加两个值或者在字符串中搜索,这是积极的反作用,因为:

  • 编译器同样知道如何做到这一点.
    • 要验证这一点,请查看其汇编输出(例如gcc -S)或反汇编机器代码
  • you're artificially restricting its choices regarding register allocation, CPU instructions etc., so it may take longer to prepare the CPU registers with the values needed to execute your hardcoded instruction, then longer to get back to an optimal allocation for future instructions
    • 编译器优化器可以在指定不同寄存器的等价性能指令之间进行 Select ,以最小化它们之间的复制,并且可以这样的方式 Select 寄存器,即单个内核可以在一个周期内处理多条指令,而强制通过特定寄存器执行所有操作将使其序列化.
      • 公平地说,GCC有办法表达对特定类型寄存器的需求,而不会将cpu限制到确切的寄存器,仍然允许这样的优化,但这是我见过的唯一解决这一问题的内联汇编
  • 如果明年新的CPU型号推出另一条指令,该指令对于相同的逻辑操作要快1000%,那么编译器供应商更有可能更新他们的编译器以使用该指令,从而使您的程序在重新编译后受益,而不是您(或当时的软件维护人员)
  • 编译器将为它所讲述的目标体系 struct Select 一种最佳方法:如果您硬编码一个解决方案,那么它将需要是最低公分母的解决方案,或者是适用于您的平台的#ifdef版解决方案
  • 汇编语言不像C++那样可移植,无论是跨CPU还是跨编译器,而且即使您似乎移植了一条指令,也有可能犯错误,重新寄存器是安全的,参数传递约定等等.
  • 其他程序员可能不知道或不熟悉汇编语言

我认为值得记住的一个观点是,当C被引入时,它必须赢得许多对生成的机器代码大惊小怪的汇编语言程序员的支持.当时机器的CPU能力和RAM较少,你可以打赌人们会对最微小的事情大惊小怪.优化器变得非常复杂,并且还在不断改进,而x86等处理器的汇编语言变得越来越复杂,它们的执行流水线、缓存和其他影响其性能的因素也变得越来越复杂.您不能再仅仅从每条指令的周期表中添加值了.编译器编写人员花时间考虑所有这些微妙的因素(特别是那些为CPU制造商工作的因素,但这也增加了其他编译器的压力).现在,汇编语言程序员要在任何重要的应用程序中平均出比优秀优化编译器生成的代码效率高得多的代码效率是不切实际的,而且他们极有可能做得更差.因此,组装的使用应该限制在它真正产生可测量和有用的差异的时候,值得耦合和维护成本.

C++相关问答推荐

从STdin读写超过4096个字节

什么C代码将确定打开的套接字正在使用的网络适配器?

在使用GTK 4 Columnview列表模型时,如何为多列添加排序函数.C编码,Linux/GNOME环境

如何使用Python C API实现多线程程序?

使用NameSurname扫描到两个单独的字符串

从组播组地址了解收到的数据包长度

为什么删除CAP_DAC_OVERRIDE后创建文件失败?

使用C时,Windows CMD中的argc参数是否包含重定向命令?

如何使用[BTStack]BLE发送大型(>;2kb)信息包

如何识别Linux中USB集线器(根)和连接到集线器(根设备)的设备(子设备)?

C I/O:在Windows控制台上处理键盘输入

在C中包装两个数组?

不使用任何预定义的C函数进行逐位运算

表达式x&;&;(~x)应该返回1还是0?它依赖于编译器吗?

c如何传递对 struct 数组的引用,而不是设置 struct 的副本

指向返回 struct 成员的指针,安全吗?

将数组中的所有元素初始化为 struct 中的相同值

Linux memcpy 限制关键字语法

是否可以在多字 C 类型中的任何位置混合存储和类型限定符?

多行表达式:C 编译器如何处理换行符?