assembly 如何推理组装速度?

9rnv2umw  于 2022-12-04  发布在  其他
关注(0)|答案(1)|浏览(140)

我想学习如何推理汇编的速度。我实现了几种不同的方法来反转一个字节的位。其中一种使用了一种算法:

rev_u8_a:
    movzx   eax, dil
    mov     ecx, 2149582850
    imul    rcx, rax
    movabs  rdx, 36578664720
    and     rdx, rcx
    movabs  rax, 4311810305
    imul    rax, rdx
    shr     rax, 32
    ret

另一个使用查找表:

rev_u8_d:
    movzx   eax, dil
    lea     rcx, [rip + .L__unnamed_1]
    movzx   eax, byte ptr [rax + rcx]
    ret

第一个是8条指令,第二个是3条,但是第一个是寄存器,第二个访问内存。我如何去推理哪一个可能更快?在这两段代码中,哪一个更快?

uhry853o

uhry853o1#

要说哪种处理器最快并不容易,因为现代处理器非常复杂,尤其是x86-64处理器。
首先,处理器以pipelined的方式执行指令,以便重叠操作,如获取指令、解码指令、执行指令。某些指令可能比其他指令花费更多的周期来完成。例如,imul rcx, rax在Skylake上花费3个周期来完成,而and rdx, rcx花费1个周期。当执行多个指令时,它变得复杂。实际上,现代处理器可以执行multiple instruction in parallel during a given cycle。为此,它们跟踪指令之间的dependencies。一些指令可能有很高的延迟,但每个周期可以发出一条新指令,而另一些指令则不能很好地流水线化。例如,3个imul在不同寄存器上的操作在Skylake上需要大约5个周期来完成,而1个imul需要3个周期。关于如何使用代码,更重要的是减少其等待时间或指令数。实际上,由于x86-64指令被分解成微指令(即uop),这就更加复杂了。(宏融合)因此要生成1个微指令,1条指令就可以生成一个或多个微指令。处理器有一个完整的部分专门用于取指令,对它们进行解码,将它们转换成微指令等:另一部分负责指令的执行以及它们在许多执行单元上的调度:后端。在大多数处理器上,执行单元并不完全相同,因此调度指令非常复杂,特别是因为处理器应该集中在critical path上,以便在最少的周期内执行指令。实际上,微操作在许多端口上调度,每个端口可以执行有限的微操作类型列表。还有许多其他事项需要考虑:寄存器X1 E4 F1 X,因此为了避免/打破一些错误依赖性并增加并行性的量,以X1 E5 F1 X方式执行指令,因此为了增加并行性的量并减少停顿,预测存储器存取和分支,(例如,参见speculative execution),微指令被高速缓存,多个线程可以同时在同一内核上运行并共享资源(见SMT),uops can be fused too等,所有这些都只是触及了现代处理器如何工作的表面,现代x86-64处理器的复杂性类似于巨大的人类城市。
LLVM-MCAuiCA之类的工具(据@PeterCordes说,这显然更好)来分析相对较大的代码,并了解处理器如何在实践中执行指令。它们中没有一个在实践中是好的,因为在运行时有许多事情要考虑。例如,一个代码在该高速缓存热的时候可以很快,在冷的时候可以很慢。代码的大小和内存访问模式一样重要。一些在芯片上实现的算法通常没有公开的文档(例如预取器)。尽管如此,像LLVM-MCA这样的工具可以很好地理解在简单代码中可能发生的情况(不考虑循环、分支未命中预测、缓存未命中等)。
在实践中,当高速缓存是冷的时,第一个代码可以更快,因为从DRAM获取数据通常需要几十纳秒当该高速缓存是热的,即数据在L1高速缓存中时,第二个通常可以更快(更少的微操作和更低的等待时间)。因此,如果LUT很小并且在循环中使用该代码,则第二代码可能更快。如果该代码执行一次,使用前者可能是一个更好的解决方案。2如果多个线程在同一个内核上运行,事情就有点复杂了。3性能与目标处理器紧密相关:一些处理器具有3个加载端口,而其它处理器可能仅具有1个加载端口,L1高速缓存的延迟在一个处理器上可以是3个周期,而在另一个处理器上可以是4个周期,两种不同架构之间的延迟和交互吞吐量可能非常不同(例如,苹果M1 VS ARM Cortex-A53,或者英特尔Skylake VS AMD挖掘机)。最好的做法是编写几个适合您的实际用例的基准测试。在编写基准测试时,您应该非常小心,因为一个糟糕的基准测试可能会导致截然不同的结论。首先,您可以阅读:绩效评估的惯用方式?。

相关问题