【Microarchitecture of Intel and AMD CPU】 2 Out-of-order execution

Intel 的第六代微处理器,从PPro开始,提供了一种重要的技术提升,乱序执行。如果一条指令的输入因为某些原因在当前时刻还未准备好,那么我们可以尝试执行这条指令后面的指令。当然,处理器需要检查时候后面的指令需要前面的指令的执行结果。如果每一条指令都依赖于前一条指令的结果,那么这就叫做依赖链。

判断输入依赖关系的逻辑,和一旦其所依赖的数据一旦准备好,就立即执行机制已经就绪,这使得处理器可以在同一时间并行做多件事。如果我们需要进行加法或者乘法,并且他们指令互不依赖,那么我们就可以同时执行他们,因为我们使用两种不同的执行单元。但是我们不能同时执行两个乘法指令,如果我们只有一个乘法单元。

处理器一般按照顺序进行流水,以增加吞吐量。如果浮点加法需要4拍,并且执行单元完全pipeline,那么我们可以在时间T开始执行一个加法,在T+4时,将会得到加法的结果;在T+1时执行另一笔加法,在T+5时得到下一笔的结果。这个技术的优势将会得到最大化,如果code被组织成连续之间没有依赖关系的形式。

2.1 指令分解为uops

乱序执行的微处理器将会将执行分解为微操做,简记为uops. 一个简单的指令,比如 ADD EAX,EBX 通常是一条uop,然而ADD EAX,[MEM1] 通常会被分解为两条指令:

1)从MEM1处加载数据到临时寄存器;

2)将临时寄存器和EAX的值累加到EAX上。

指令ADD [MEM1],EAX则会分解为三条uop

1)从MEM1处加载数据到临时寄存器;

2)将临时寄存器和EAX的值累加到临时寄存器上;

3)将临时寄存器的值写回memory。

这个操作的优势就是uops可以被乱序执行

; Example 2.1. Out of order processing
mov eax, [mem1]
imul eax, 5
add eax, [mem2]
mov [mem3], eax

此处,ADD EAX,[MEM2] 指令会被分解为两条微指令。这个的好处就是可以同时加载mem2处的数据,同时执行imul的乘法。如果这些数据都不在cache中,微处理器将会在读取mem1处的数据之后,立刻读取mem2处的数据,可以远早于乘法的执行。

将指令分解为微指令也可以使得栈工作的效率提升,考虑下面的sequence

; Example 2.2. Instructions split into μops
push eax
call func

push eax指令会分解为两条uop:SUB ESP,4和MOV [ESP],EAX。这样做的优势就是SUB ESP,4可以提前执行,即使此时EAX还没有准备好。CALL指令需要ESP的最新值(将EBP设置为ESP的值)。 如果 PUSH指令没有被分解为两条微指令,那么CALL指令需要等待PUSH指令的执行完毕。幸好我们使用了微指令,栈指针的基本不会耽误我们的程序。

2.2 寄存器重命名

考虑下面的例子:

; Example 2.3. Register renaming
mov eax, [mem1]
imul eax, 6
mov [mem2], eax
mov eax, [mem3]
add eax, 2
mov [mem4], eax

这个代码片段中执行了两个毫不相关的指令,【mem1】*6 和【mem2】+2。如果最后三条指令使用不同的寄存器,那么它们就明显的不相关。实际上,微处理器可以实现这个技术。它会为后面的三条指令使用不同的临时寄存器,这样就可以同时执行加法和乘法了。IA32指令只给了我们7个32bit的通用寄存器,通常我们会用光。所以我们没法给每个计算都配置一个新的寄存器。但是微处理器有大量的临时寄存器可以使用。微处理器可以重命名任意的临时寄存器,以代表逻辑架构寄存器EAX。

寄存器重命名可以十分的自动化并且以非常简单的方式工作。每次一条指令想要写入逻辑寄存器,处理器都会为这个逻辑寄存器分配一个新的临时寄存器。上面例子中的第一条指令要写如EAX,所以一个新的临时寄存器会被分配。换句话说,乘法指令将要使用两个不同的寄存器,一个用于输入,一个用于输出。(译者注:原例 imul eax 6 是将eax的值乘6后再写入EAX)下面的例子介绍了这样做的优势

; Example 2.4. Register renaming
mov eax, [mem1]
mov ebx, [mem2]
add ebx, eax
imul eax, 6
mov [mem3], eax
mov [mem4], ebx

假如【MEM1】在cache中,但是【MEM2】不在。这意味着乘法将会在加法之前启动。使用临时寄存器的优势就是,即使后面再执行加法,那么我们也不会破坏eax原始的值。如果我们使用同一个寄存器既做输入又做输出,那么乘法需要等待ebx的加载完毕,然后加法才能执行。

在所有的指令执行完毕之后,代码段中最新的临时寄存器中的值将会被写入逻辑架构EAX寄存器。这个阶段又叫做retirement(退休)。

所有的上述通用寄存器,栈寄存器,标志位,浮点寄存器和向量寄存器和段寄存器都可以被重命名。多数处理器不允许控制字和浮点状态字被重命名,这就是代码修改这些寄存器较慢的原因。


翻译自【Microarchitecture of Intel and AMD CPU  An optimization guide for assembly programmers and compiler makers

                                                                                                                    -------------------欢迎关注我的公众号《处理器与AI芯片》

深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值