openstack-notes

前言

CPU(中央处理器)作为电脑最重要的一个模块,出生就自带高科技的光环,有人做过对比,制作一个CPU和制作一个操作系统哪个难度更大一些?这个暂且不论,但是于我而言,CPU本身自带一种魔力,让人情不自禁的去了解它。对于CPU与计算机,在具备了一些基本的知识之后,始终有一些问题缠绕着我。CPU是怎么执行代码的?CPU里面到底是什么样子的?CPU多核设计的核到底是什么?CPU是怎么和硬件主板打交道的?…… 恰好最近看了一些Intel Skylake CPU架构(Intel第9代处理器)的一些文章,这里把自己的理解写一下,做个记录,持续补充更新。

关于上述问题,可能需要很长的时间去一一寻找答案,本篇首先记录一下CPU core里面的架构。水平有限,如有问题,请各位批评指导。

基本知识

在开始之前,首先需要明确现代CPU里有多个核,比如我们经常听的四核八核等等。Core与CPU的关系图如下图所示。示意图中的CPU有四个Core(核),Core与Core之间通过Ring(环形总线)连接起来,每一个核就是一个独立的计算单元,Core本身自带L1 Cache与L2 Cache。L3是所有的Core共享。L1又划分为指令Cache与数据Cache两类。关于Cache的一些介绍,可以下滑至文末查看。本篇重点在于介绍CPU的Core里面的执行流程与部件。

一、CPU指令的执行过程

1.取指令阶段

2.指令译码阶段

3.执行指令阶段

4.访存取数阶段

5.结果写回阶段

二、CPU指令流水线

标量流水计算机工作方式

超标量流水计算机工作方式

三、指令的相关性

1.数据相关

  1. 采用编译的方法 编译程序通过在两条相关指令之间插入其他不相关的指令(或空操作指令)而推迟指令的执行,使数据相关消失,从而产生没有相关性的程序代码。这种方式简单,但降低了运行效率。
  2. 由硬件监测相关性的存在,采用数据旁路技术设法解决数据相关 当前一条指令要写入寄存器而下一条指令要读取同一个寄存器时,在前一条指令执行完毕、结果数据还未写入寄存器前,由内部数据通路把该结果数据直接传递给下一条指令,也就是说,下一条指令所需的 操作数不再通过读取寄存器获得,而是直接获取。这种方式效率较高,但控制较为复杂。

2.资源相关

3.控制相关

  1. 延迟转移法 由编译程序重排指令序列来实现。其基本思想是“先执行再转移”,即发生转移时并不排空指令流水线,而是继续完成下几条指令。如果这些后继指令是与该转移指令结果无关的有用指令,那么延迟损失时间片正好得到了有效的利用。
  2. 转移预测法 用硬件方法来实现。依据指令过去的行为来预测将来的行为,即选择出现概率较高的分支进行预取。通过使用转移取和顺序取两路指令预取队列以及目标指令 Cache,可将转移预测提前到取指令阶段进行,以获得良好的效果。

四、指令的动态执行技术

1.指令调度

2.乱序执行技术

3.分支预测

Core架构图

话不多说,对于Skylake而言,CPU中的Core的架构图如下所示:

咋一看这个图,感觉超级复杂,各种连线,各种模块。其实对于core而言,主要目的就是执行各种运算,而剩下的就是就是core对执行运算之前的处理。对于上图,我们可以直接把Core划分为三个部分看,一个部分是前端(Front-end)也就是图中黄色的部分,另外一个就是(EU)执行单元了,也就是图中浅绿色的部分,第三块就是数据缓存,专门给执行单元提供执行指令期间所需要的数据.

Front-end(Core前端)

首先看Front-end,Front-end的主要目的就是从内存里提取各种各样的X86指令,然后对指令进行译码,融合优化等操作,把X86指令转化为最适合执行单元执行的微指令流传递给执行单元。Front-End的存在就是为了让执行单元时刻保持繁忙,将CPU的性能完全发挥出来。对于Core的Front-end模块,从上往下看,这部分主要包含:

Execution engine (执行单元)

Front-End的存在就是为了让执行单元时刻保持繁忙,那么执行单元的最主要的目的就是执行指令,运算。这也是一个core中最根本的单元。

当被AQ或者IDQ(分配单元)优化过后的微指令来到执行单元时,首先最先传输到

从上图中可以看到,对于8个端口,其中Port0,Port1,Port5,Port6负责各种常见运算(整数,浮点,除法,移位,AES加密,复合整数运算……),而Port2,Port3负责从下层的指令缓存提取数据,port4负责存储数据到L1缓存。Port7挂载地址生成单元(AGU address generation unit).

数据缓存系统 (L1数据缓存)

图中紫色的模块,在EU(执行单元)在执行指令时候,L1数据Cache负责供给执行指令期间所需要的数据。从图中可以看到L1数据缓存是8-路并行数据缓存,L1数据缓存可以通过数据页表地址缓存从L2提取数据与存储数据。

至此,借着Intel第九代Skylake架构图。我们大概把CPU core里面的模块过了一遍,也对CPU core执行指令的过程有了一个大概的了解。当时留下的坑也很多,对于细节问题,后续需要逐渐了解。在了解core之后,后续还会完善core和core协同组成一个完整的CPU,以至于CPU和外设,CPU与CPU之间的协同工作。