一个故事看懂CPU的SIMD技术
好久不见,我叫阿Q,是CPU一号车间的员工。我所在的CPU有8个车间,也就是8个核心,咱们每个核心都可以同时执行两个线程,就是8核16线程,那速度杠杠滴。
我所在的一号车间,除了负责执行指令的我,还有负责读取指令的小A,负责指令译码的小胖和负责结果回写的老K,我们几个各司其职,一起完成执行程序的工作。
一个简单的循环
那天,我们遇到了一段代码:
void array_add(int data[], int len) {
for (int i = 0; i < len; i++) {
data[i] += 1;
}
}
循环了好几百次之后,才把这段代码执行完成,每次循环都是做简单又重复的工作,把我累得够呛。
一旁负责结果回写的老K也是累的满头大汗,吐槽道:“每次都是取出来加1又写回去,要是能一次多取几个数,批量处理就好了”
老K的话让我眼前一亮,对啊,能不能批量操作呢?
心里一边想着,一边继续干活了。
繁忙的一天很快结束了,转眼又到了晚上,计算机关机后,我把大家召集了起来。
“兄弟们,还记得咱们白天遇到的那个循环吗?”
“你说哪个循环,咱们这一天可执行了不少循环呢”,小A说到。
“就是那个把整数数组每个元素都加1的那个循环”
“我想起来了,那循环怎么了?有什么问题吗?”
我看了老K一眼,说道:“我在想今天老K的话,像这种循环,每次都是取出来加1又写回去,一次操作一个数,效率太低了,咱们要是升级改造一下,支持一次取出多个数,批量加1,这样岂不是快很多?”

老K一听来了兴趣,“这敢情好,你打算怎么做?”
“这我还没想好,大家有什么建议吗?”
一旁负责指令译码的小胖说道:“可以新增一条指令,专门用来一次取出多个数据来加1”
“不行不行,不能限的这么死,今天是加1,万一下次是加2呢?指令里面不能限制为1”
“那如果每个数据要加的是不一样的怎么办?”
“你这么一说,那万一不是加法,是减法,乘法怎么办?”
“还有啊,···”
大家开始七嘴八舌讨论了起来,没想到一个小小的加法循环,一下子引出了这么多问题来,这是我们没想到的。
并行计算
随着讨论的深入,我觉得已经超出了咱们一号车间能把控的范围,需要上报给领导,组织八个车间代表一起来商讨。
领导一听说有提高性能的新技术,马上来了兴趣,很快便开会组织大家一起来商讨方案。

“都到齐了是吧,阿Q你给大家说一下这个会议的目的”,领导说到。
我站了起来,开始把我们遇到的问题和想法跟大家讲了一遍。
“是这样的,我们一号车间那天遇到了一段循环代码,循环体的内容很简单,就是给数组中的每一个元素加1。我们执行的时候,就是不断取出每一个元素,然后将其执行加法计算后,再写回去。这样一个一个来加1,我们感觉太慢了, 要是可以一次多取几个,并行加1,那一定比一个一个加快上不少。”
我刚说完,大家都开始小声议论起来。
“我看出来了,这其实就是并行计算!”,二号车间小虎一语道出了关键。
六号车间小六问道:”阿Q,你们已经有方案了吗?“
“还没有,这正是今天开会的目的,因为情况有点复杂,还需要大家一起来出出主意”
“好像并不复杂嘛”
“我上面举的例子只是一个简单的情况,并行计算还可能不是固定的数,可能是一个数组和另一个数组相加。还有可能不是整数相加,而是浮点数,甚至,还可能不是加法,而是减法或者乘法,再或者不是算术运算,而是逻辑运算”
我刚一说完,大家又开始窃窃私语交流起来。
“我琢磨着你说的这一系列东西,咱们是要新增一套专门用来并行计算的指令集啊”,小虎说道。
“这可是大工程啊”
“是啊···”
这时,小六又问道:“咱们的计算的时候,都是把数据读取到寄存器进行的,可这寄存器一次只能装一个数,怎么一次读取多个数据呢?”
“可能需要新增一些容量大一些的寄存器,比如128bit长度,可以同时容纳4个32位的整数”

“有这个必要吗?咱们是通用CPU,又不是专门做数学计算的芯片,搞这些东西干嘛?”,四号车间代表提出了质疑。
我也不甘示弱:“那可太有必要了,在图像、视频、音频处理等领域,有大量这样的计算需求,咱们得提升处理这些数据的能力”
见我们争执不下,领导拍了拍桌子,会场一下安静了下来。
“我觉得阿Q说的有道理,咱们确实需要提升处理这类数据运算的能力了。不过不用一下搞那么复杂,先支持整数并行运算就行了。新增寄存器这个也不用着急,可以先借用一下浮点数运算单元FPU的寄存器。这件事先这么定下来,具体的方案你们再继续讨论。”,说完便离开了会议室。
领导不愧是领导,几句话就把我们安排的明明白白。
SIMD
又经过一阵紧张的讨论,我们终于敲定了方案。
我们借用浮点数运算单元的寄存器,还给它们起了新的名字:MM0-MM7。因为是64位的寄存器,所以可以同时存储两个32位的整数或者4个16位整数或者8个8位的整数。
我们还新增了一套叫MMX的指令集,用来并行执行整数的运算。

我们把这种在一条指令中同时处理多个数据的技术叫做单指令多数据流(Single Instruction Multiple Data),简称SIMD。
有了这套指令集,咱们处理这类整数运算问题的速度快了不少。
不过渐渐地发现了两个很麻烦的问题:
第一个问题,因为是借用FPU的寄存器,所以当执行SIMD指令的时候,就不能用FPU计算单元,反过来也一样,同时使用的话就会出乱子,所以要经常在不同的模式之间切换,实在是有些麻烦。
另一个更重要的问题,咱们这套指令集只能处理整数的并行运算,可现在浮点数的并行运算越来越多,尤其是图像、视频还有深度学习的一些数据处理,浮点数情况越来越多,这时候都派不上用场。
我们把这些问题给领导做了汇报,看到我们已经做出的成绩,领导终于同意继续升级。
这一次,我们扩展了一套新的SSE指令集出来,新增了XMM0-XMM7总共8个128位的寄存器,再也不用跟FPU共享寄存器了。而且位宽加了一倍,能容纳的数据更多了,能同时处理的数据自然也变多了。
后来,我们又不断的修改升级,不仅支持了对浮点数并行处理,还推出了新一代的AVX指令集,把寄存器再一次扩大为256位,现在我们的SIMD技术更加先进,处理数据运算的能力越来越强了!
往期TOP5文章
一个故事看懂CPU的SIMD技术的更多相关文章
- 一个故事看懂CPU的TLB
Hi,我是CPU一号车间的阿Q,还记得我吗,真是好久不见了- 我所在的CPU是一个八核CPU,就有八个工作车间,那运行起来速度杠杆的- 虚拟地址翻译 一大早,我们一号车间MMU(内存管理单元)部门的小 ...
- 一个故事看懂HTTPS
我是一个浏览器,每到夜深人静的时候,主人就打开我开始学习. 为了不让别人看到浏览记录,主人选择了"无痕模式". 但网络中总是有很多坏人,他们通过抓包截获我和服务器的通信,主人干了什 ...
- 一个故事看懂AI神经网络工作原理
我是一个AI神经元 我是一个AI神经元,刚刚来到这个世界上,一切对我来说都特别新奇. 之所以叫这个名字,是因为我的工作有点像人类身体中的神经元. 人体中的神经元可以传递生物信号,给它输入一个信号,它经 ...
- 一个故事看懂Linux文件权限管理
前情回顾: 我通过open这个系统调用虫洞来到了内核空间,又在老爷爷的指点下来到了sys_open的地盘,即将开始打开文件的工作. 详情参见:内核地址空间大冒险:系统调用 open系统调用链 我是一个 ...
- 一文看懂大数据的技术生态圈,Hadoop,hive,spark都有了
一文看懂大数据的技术生态圈,Hadoop,hive,spark都有了 转载: 大数据本身是个很宽泛的概念,Hadoop生态圈(或者泛生态圈)基本上都是为了处理超过单机尺度的数据处理而诞生的.你可以把它 ...
- zz:一个框架看懂优化算法之异同 SGD/AdaGrad/Adam
首先定义:待优化参数: ,目标函数: ,初始学习率 . 而后,开始进行迭代优化.在每个epoch : 计算目标函数关于当前参数的梯度: 根据历史梯度计算一阶动量和二阶动量:, 计算当前时刻的下降 ...
- 一个故事讲懂vue父子组件传值
作者:李佳明同学链接:https://www.jianshu.com/p/2272b6ca0f0c 一个故事讲懂vue父子组件传值 讲故事前先讲代码 父组件向子组件传值 父组件数据传递给子组件可以通过 ...
- 一个框架看懂优化算法之异同 SGD/AdaGrad/Adam
Adam那么棒,为什么还对SGD念念不忘 (1) —— 一个框架看懂优化算法 机器学习界有一群炼丹师,他们每天的日常是: 拿来药材(数据),架起八卦炉(模型),点着六味真火(优化算法),就摇着蒲扇等着 ...
- 一个故事搞懂Java并发编程
最近在给别人讲解Java并发编程面试考点时,为了解释锁对象这个概念,想了一个形象的故事.后来慢慢发现这个故事似乎能讲解Java并发编程中好多核心概念,于是完善起来形成了了这篇文章.大家先忘记并发编程, ...
随机推荐
- Centos 7.6 使用 kubekey 部署 kubesphere v3.1.0
文章目录 主要功能 硬件要求 Kubernetes版本要求 配置主机之间的免密 安装所需依赖 下载KubeKey 创建Kubernetes集群以及KubeSphere kk命令使用方式 修改配置文件 ...
- VUE项目二级菜单刷新时404 nginx
原因:vue项目的路径时虚拟路径,并不存在,所以用nginx去请求请求不到,所以vue项目做了两部调整: 1.所有的请求后端接口地址前端写死 2.nginx里把所有的接口转发后端删掉,并添加以下内容 ...
- Java泛型的那些事
1.泛型概述 1.1.为什么使用泛型 没有泛型,在编写代码时只能使用具体类型或Object类型,无法做到使用者想要使用什么类型就是类型.比如:创建一个方法,形参需要指定需要使用的数据类型,在创建方法之 ...
- 安装CentOS7出现dracut:/#……time解决办法
当选择install CentOS7以后一会就会出现错误.报错信息:就是dracut:/# ... timeout一大堆.我本来以为是我的启动盘没做好,后来我又重做了好几次都是这问题. 解决 通过搜索 ...
- 华为RH2288H服务器引导ServiceCD安装Windows Server操作系统
安装准备 ServiceCD光盘. Windows操作系统安装光盘. 物理光驱. 使用虚拟控制台远程安装操作系统时,需要准备以下软件: ServiceCD光盘或ServiceCD ISO文件. Win ...
- 【windows 访问控制】开篇、访问控制模型模型
访问控制模型的各个部分 访问控制模型有两个基本部分: 访问令牌,其中包含有关已登录用户的信息 安全描述符,其中包含用于保护安全对象 的安全信息 用户登录时 ,系统会对用户 的帐户名和密码进行身份验证. ...
- golang程序设计:Go middleware中间件以及Gin 中间件分析
先从业务开发角度出发,来逐渐引出中间件. 一.刚开始时业务开发 开始业务开发时,业务需求比较少. 当我们最开始进行业务开发时,需求不是很多. 第一个需求产是品向大家打声招呼:"hello w ...
- omnet++:cMessage、cSimpleModule、cGate
cMessage Message可以被调度(self-message).取消.从一个Gate发送出去.直接发给另一个module:所有以上,都是通过cSimpleModule来实现的. Message ...
- Vue之获取DOM元素与更新DOM后事件的特殊情况
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- bower install 报错fatal: unable to access 'https://github.com/angular/bower-angular-touch.git/'类错误解决方法
bower install时出现很多unable to access 'https://github.com/angular/bower-angular-touch.git/'类似的错误, 方法一:( ...