用大白话带你理解CPU指令集

  • 指令集与机器码

无论处于上层的软件多么的高级, 想要在CPU执行, 就必须被翻译成"机器码", 翻译这个工作由编译器来执行. 编译器在这个过程中, 要经过"编译", "汇编", "链接"几个步骤, 最后生成"可执行文件". 可执行文件中保存的是二进制机器码. 这串机器码可以直接被CPU读取和执行.

软件意义上, "指令集"实际上是一个规范, 规范汇编的文件格式.
以下为一条x86汇编代码:
mov word ptr es:[eax + ecx * 8 + 0x11223344], 0x12345678

这里可以体现出指令集的格式限制:
1. 可以使用mov指令, 但它只能有2个操作数.
2. 它的操作数长度是16 (word), 不要看到后面0x12345678就认为是32位操作数.
3. 它带有段超越前缀, 这里使用了es, 还可以使用ds, cs, ss, fs, gs. 但是只能用这几个.
4. 第一个操作数是一个内存地址, 第二个是立即数. 但是, 这个内存地址不能乱写, 写成[eax+ecx*10+0x11223344]就错了.

实际上, 一条汇编指令与一段机器码是一一对应的. 上面这段汇, 可以被x86编译器翻译成几乎唯一的一段机器码:
26 66 c7 84 c8 44 33 22 11 78 56
上面提到的1,2,3,4点如果有一个弄错, 这一步就会失败.

可以看出来, 指令集的作用, 就是告诉程序员/编译器, 汇编一定要有格式. 支持什么指令, 指令带什么限制条件, 用什么操作数, 用什么地址, 都是指令集规范的内容, 要是写错了, 就无法翻译成机器码.
指令集规范汇编, 汇编可以翻译成机器码, 机器码告诉CPU每个周期去做什么. 因此, CPU指令集是描述CPU能实现什么功能的一个集合, 就是描述"CPU能使用哪些机器码"的集合".

那机器码进入到CPU后又做什么呢?
=====================编译器和CPU的分界线========================

需要被执行的机器码先要被OS调度到内存之中, 程序执行时, 机器码依次经过了Memory--Cache--CPU fetch, 进入CPU流水线, 接着就要对它进行译码了, 译码工作生成的象是CPU内部数据格式, 微码(或者类似的格式, 这个格式不同的厂商会自己设计).

这个过程画成图就是:

软件层: 汇编语言
------------------------------------------------------------------------
接口: 汇编语言所对应的机器码
------------------------------------------------------------------------
硬件层: CPU使用内部数据结构进行运算

如果机器码代表的功能是在指令集规范内的, 这条机器码就可以生产微码, 并在CPU内正常流动. 假设机器码是错误的, 是不可以通过CPU的译码阶段的, 控制电路一定会报错. 这种情况反映在Windows里往往都是蓝屏, 因为CPU无法继续执行, 它连下一条指令在哪都不知道.

那么指令集在CPU里就代表: 只有CPU指令集范围内的指令可以被成功的译码, 并送往CPU流水线后端去执行.
和常规的想法不一样, CPU不需要任何形式的存储介质去存储指令集, 因为"译码"这个步骤就是在对指令集里规范的机器码做解码. 硬件上, 译码这件事需要庞大数目的逻辑门阵列来实现.

跳出格式这个圈子来看待这个问题. 可以说, CPU执行单元的能力, 决定了指令集的范围. 比如, CPU的执行单元有能力执行16位加法, 32位加法, 64位加法, 那么指令集里一般就会有ADD 16, ADD 32, ADD 64这样的表达方式. 如果CPU的执行单元没有电路执行AVX指令, 那么指令集里一般就没有VINSERTF128这样的指令供使用. 所以, 强有力的执行单元能够提供更多的指令集.

再来看"CPU指令集在哪里"这个问题, 回答是, CPU本身就是CPU指令集. 指令集规定CPU可以做什么事, CPU就是具体做这件事的工具. 如果一定要指定一个狭义的CPU指令集的存放位置. 那就是CPU中的"译码电路".

 

  • 对于指令集的电路理解


现代的CPU没拆过,我只在计算机组成原理实验课上用VHDL在某个实验平台上做过一个模拟的CPU。举个例子你可能比较好理解。
比如我们设计一套指令集,其中肯定有条加法指令。比如Add R1 R2 。我们可以认为这条指令的意思是计算寄存器R1中的内容和R2的和,然后把结果存到R1寄存器中。
那么经过编译后这条指令会变成二进制,比如010100010010 。这条二进制指令一共12位。明显可以分为三大部分。最前面的0101表示这是条加法指令,后面0001说的是第一个操作数是寄存器1,最后0010说的是第二个数就是寄存器2(其实实际没有这么简单的指令,至少应该区分操作数是寄存器还是直接的数据,但为了把这说的更容易理解作了简化)。我们可以通过十二根导线把这条指令输入一个CPU中。导线通电就是1,不通电就是0 。为了叙述方便我们从左到右用A0-A11给这12根导线编上号。
然后计算机会分析这条指令。步骤如下:

  1. 最开始的两根导线A0和A1,第一根有电第二根没电,就能知道这是一条运算指令(而非存储器操作或者跳转等指令)。那么指令将被送入逻辑运算单元(ALU)去进行计算。其实很简单。只要这两根线控制接下来那部分电路开关即可。
  2. 接下来的A2和A3,01表示加法,那么就走加法运算那部分电路,关闭减法等运算电路。
  3. A4-A7将被送入寄存器电路,从中读取寄存器保存的值。送到ALU的第一个数据接口电路上。
  4. 后面的A8-A11同样被送入寄存器选择电路,接通R2寄存器,然后R2就把值送出来,放到ALU的第二个数据接口上。
  5. ALU开始运算,把两个接口电路上的数据加起来,然后输出。
  6. 最后结果又被送回R1。

基本上简单的运算计算机就是这么操作的。他其实不知道你那些指令都是什么意思。具体的指令编程机器码后就会变成数字电路的开关信号。其中某几段会作为控制信号,控制其他部分的数据走不同的电路以执行运算。他没有一个地方保存着如何翻译这些机器码的字典,所有机器码的意义都被体现在整个电路的设计中了。
当然,从汇编到机器码这步是汇编程序翻译的。汇编程序当然知道某条指令要翻译成什么样的机器码。

 

  • 总结

对于指令集的简单理解,它就是CPU中一堆实现各种计算的逻辑门电路,支持执行很多格式的机器码。

而指令集,就是对CPU支持的机器码格式规范的一个描述。

引用原作者的理解:

软件意义上, "指令集"实际上是一个规范, 规范汇编的文件格式。

CPU指令集是描述CPU能实现什么功能的一个集合, 就是描述"CPU能使用哪些机器码"的集合"。

 

本文转载于知乎:https://www.zhihu.com/question/20793038/answer/16198162

  • 19
    点赞
  • 64
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: XGBoost(eXtreme Gradient Boosting)是一种机器学习算法,通过集成多个弱学习器的预测结果来构建强学习器。它基于梯度提升框架,使用变种的决策树作为弱学习器,并在训练过程中优化损失函数。 XGBoost的核心思想是迭代地增加决策树的规模,每次新建一个决策树并进行训练,在训练过程中,根据之前决策树的预测结果与真实标签之间的差异,调整模型参数,使得模型能够更好地拟合训练数据。同时,为了防止过拟合,XGBoost采用了正则化方法。 在训练过程中,XGBoost使用了梯度提升技术优化损失函数。梯度提升是通过最小化损失函数的负梯度来逐步优化模型的方法。XGBoost在每次迭代中,计算损失函数的一阶导数和二阶导数,以此来训练新建的决策树,并通过梯度提升的方式将新决策树集成到模型中。 XGBoost还引入了一些创新的技术来提高模型性能,例如,使用特定的数据结构(稠密压缩列存储)存储训练数据以优化内存使用;通过按特征值排序的方式加速特征分裂的搜索;使用分布式计算框架进行大规模训练等。 总的来说,XGBoost是一种强大且高效的机器学习算法,能够处理各种类型的数据,并在许多机器学习竞赛中取得了优异的成绩。它的优点包括可解释性强、鲁棒性好、可扩展性强等,在工业界和学术界都得到了广泛应用。 ### 回答2: XGBoost(eXtreme Gradient Boosting)是一种广泛应用于机器学习领域的集成学习算法。它的基本原理是通过多个弱学习器的集成来构建一个更强大的模型。 XGBoost的主要特点包括: 1. 高度灵活:XGBoost可以应用在各种数据和任务上,包括分类、回归和排序等。 2. 高效性能:XGBoost采用了并行计算技术,使得模型训练和预测速度都非常快。 3. 可解释性:XGBoost提供了特征重要性排序功能,可以帮助我们理解模型的决策过程。 4. 鲁棒性:XGBoost通过正则化项和剪枝方法,可以有效地减少过拟合的风险。 XGBoost的工作原理如下: 1. 初始化:首先,将一个简单的模型作为初始模型,一般是选择一个常数值作为初始预测。 2. 偏差修正:计算初始预测值与实际目标值之间的差异,得到残差。然后,使用回归树来拟合这些残差。 3. 加法模型:将拟合的回归树与初始模型进行加权相加,得到新的预测值。即将之前的预测值与回归树的预测值相加,得到新的预测值。 4. 更新残差:计算新的预测值与实际目标值之间的差异,得到新的残差。 5. 迭代:重复上述过程,不断迭代生成新的回归树,并更新预测值和残差,直到模型收敛或达到预设的迭代次数。 在每一轮迭代中,XGBoost通过梯度和近似的海森矩阵对目标函数进行优化,选择最佳的分割点和叶子权重来构建回归树。同时,通过正则化项对树的复杂度进行控制,避免过拟合现象。 总之,XGBoost通过迭代的方式不断优化模型的预测能力,同时考虑了数据结构、特征重要性和模型复杂度等因素,使得其在各种机器学习任务中表现出色。 ### 回答3: XGBoost(eXtreme Gradient Boosting)是一种机器学习算法,是基于决策树的集成学习方法。它通过多个弱分类器的集成来构建一个强分类器。 XGBoost的核心思想是通过不断迭代训练,通过添加弱分类器并纠正先前的错误来提高整体模型的准确率。在每轮迭代中,XGBoost会计算每个样本的梯度信息,并使用这些信息来训练下一个弱分类器。新的弱分类器将根据梯度信息来修正上一轮分类器的错误。 与传统的Gradient Boosting算法相比,XGBoost通过引入一些改进来提高模型的性能。其中一个改进是使用了正则化项,以避免模型过拟合。另一个改进是引入了二阶梯度信息,以更准确地估计每个样本的预测误差。 XGBoost还使用了一种特殊的数据结构,称为"分布式虚拟内存",以在大规模数据集上高效地进行训练。此外,XGBoost还具有并行计算能力,可以利用多核处理器和分布式计算资源来加速训练过程。 XGBoost在多个机器学习竞赛中取得了显著的成绩,并被广泛应用于实际问题中。它可以用于分类问题和回归问题,还可以处理缺失值和异常值。XGBoost具有较高的预测准确性和鲁棒性,同时也具备良好的解释性,可以帮助我们理解特征的重要性和模型的逻辑。 总之,XGBoost是一种强大的机器学习算法,它通过集成多个弱分类器来构建一个准确性较高的分类器。它的优点包括高性能、良好的鲁棒性和解释性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值