performance - 为什么我们要在汇编中使用 CPU 寄存器,而不是直接使用内存呢?

标签 performance assembly cpu-architecture cpu-registers

我有一个关于 assembly 的基本问题。

如果算术运算也可以在内存上运行,为什么我们还要费心只在寄存器上进行算术运算呢?

例如,以下两种情况都会(本质上)导致计算出相同的值作为答案:

片段1

.data
    var dd 00000400h

.code

    Start:
        add var,0000000Bh
        mov eax,var
        ;breakpoint: var = 00000B04
    End Start

片段2

.code

    Start:
        mov eax,00000400h
        add eax,0000000bh
        ;breakpoint: eax = 0000040B
    End Start



据我所知,大多数文本和教程主要在寄存器上进行算术运算。使用寄存器是不是更快?

最佳答案

如果您查看计算机体系结构,您会发现一系列内存级别。靠近 CPU 的设备速度快、成本高(每比特),因此体积小,而另一端则有大、慢且便宜的内存设备。在现代计算机中,这些通常类似于:

 CPU registers (slightly complicated, but in the order of 1KB per a core - there
                are different types of registers. You might have 16 64 bit
                general purpose registers plus a bunch of registers for special
                purposes)
 L1 cache (64KB per core)
 L2 cache (256KB per core)
 L3 cache (8MB)
 Main memory (8GB)
 HDD (1TB)
 The internet (big)

随着时间的推移,越来越多级别的缓存被添加 - 我还记得 CPU 没有任何板载缓存的时候,而我还没有老!如今,HDD 配备了板载缓存,并且互联网可以在任意位置进行缓存:内存中、HDD 上,也可能在缓存代理服务器上。

离开 CPU 的每一步,带宽都会急剧下降(通常是数量级),延迟也会增加。例如,HDD 可能能够以 100MB/s 的速度读取,延迟为 5ms(这些数字可能并不完全正确),而主内存可以以 6.4GB/s 的速度读取,延迟为 9ns(六阶)震级!)。延迟是一个非常重要的因素,因为您不想让 CPU 等待的时间超过其必须的时间(对于具有深层管道的架构尤其如此,但这是另一天的讨论)。

这个想法是,您经常会一遍又一遍地重复使用相同的数据,因此将其放入小型快速缓存中以供后续操作是有意义的。这称为时间局部性。局部性的另一个重要原则是空间局部性,它表示彼此靠近的内存位置可能会在大约同一时间被读取。正是由于这个原因,从 RAM 读取将导致读取更大的 RAM block 并将其放入 CPU 缓存中。如果没有这些局部性原则,那么内存中的任何位置在任何时候都有相同的机会被读取,因此无法预测接下来将访问什么,以及所有级别的缓存世界上的速度不会提高。您不妨只使用硬盘驱动器,但我确信您知道计算机在分页时突然停止的感觉(这基本上是使用 HDD 作为 RAM 的扩展)。从概念上讲,除了硬盘之外没有内存是可能的(许多小型设备只有一个内存),但这与我们熟悉的相比会慢得令人痛苦。

拥有寄存器(并且只有少量寄存器)的另一个优点是它可以让您拥有更短的指令。如果您的指令包含两个(或更多)64 位地址,那么您将拥有一些很长的指令!

关于performance - 为什么我们要在汇编中使用 CPU 寄存器,而不是直接使用内存呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45581423/

相关文章:

MySQL 关系分区查询性能

c - MIPS的堆栈让我脑洞大开

组装32位左移器

java - 在游戏中使用 'Number' 类而不是原语?

performance - 复制!并在 Julia 中切片

linux - 为什么 printf 会覆盖 ECX 寄存器?

c - Loop unrolling and its effects on pipelining and CPE(有解法,但不懂)

memory - 如何以编程方式判断 Linux 处于 PAE 模式还是非 PAE 模式?

c++ - 通过施加内存压力来降低CPU频率

Android:辅助功能服务中的 getRootInActiveWindow 会导致 ANR 吗?