作者|码农的荒岛求生

来源|码农的荒岛求生

有同学问了这样一个问题:既然CPU内部的寄存器数量有限,容量有限,那么我们使用的庞大的数据结构是怎样装入寄存器供CPU计算的呢

这篇文章就为你讲解一下这个问题。

内存与数据

真正有用的程序是离不开数据的,比如一个int、一个float等,这些都是非常简单的数据。

当然也有非常复杂的数据,这样的数据通常在内存中以数据结构的形式组织起来,比如你创建了一个数组、一个链表、创建了一棵树、一张图,就像这样:

那么很显然这些数据存放在内存中,而且这些数据在不同的场景下有不同的大小,从数B、数KB到数百GB都有可能,与此同时,CPU内部的寄存器数量是固定的,容量也是极其有限的,那么CPU是如何利用有限的资源操作庞大的数据结构呢?

要回答这一问题,我们需要要认识一位农夫,因为他不生产数据,他只是数据的搬运工,这位农夫就是。。

搬运数据的机器指令

你没有看错,这位农夫就是我们之前多次提到的机器指令。

机器指令中除了负责逻辑运算、执行流控制、函数调用等指令外,还有一类指令,这类执行只负责和内存打交道,典型的就是精简指令集架构中的Load/Store机器指令,即内存读写指令(复杂指令集没有单独的内存读写指令)。

原来,从宏观上看的话,存放在内存中的数据,比如一个数组,可能会非常庞大,但是具体到代码,每一个步骤操作的数据又会非常简单,就像这样:

int* huge_arr = new int[1 * 1024* 1024 *1024];

我们创建了一个长度为1G的数组,每个int 4字节,则这个数组的大小就是4GB,这显然是一个很庞大的数组。

对于这样的数据,我们通常都会怎么使用呢?

最常见的情况可能是遍历一边,然后对每个字符进行一个简单操作,这里以计算数组之和为例:

long int sum = 0;
for (int i = 0; i < 1 * 1024* 1024 *1024; i++) {sum += huge_arr[i];
}

虽然整个数组多达4GB,但具体到每一步我们一次只能操作一个元素,就像这里的:

sum += huge_arr[i];

这行代码翻译成机器指令可能是这样的,我们假设此时i为100:

load $r0 100($r2)
add $r1 $r1 $r0

(注意,实际当中编译器不会傻傻的生成100这样的常数,这里代码仅用来方便讲解问题)。

第一行指令中数组首地址存放在寄存器r2中,100($r2)表示数组首地址+100,这样我们就能得到huge_arr[100]的地址了,然后将该地址中的值利用load指令加载到寄存器r0中。

第二行就简单多了,r1寄存器中保存的是sum的值,该行指令执行过后r1中的值就已经加上了huge_arr[100]。

现在你应该能看出来了吧,虽然我们不能把整个数组加载到寄存器供CPU计算,但这其实是没有必要的,因为我们一次只能操作数组中的一个元素,我们只需要把这一个元素加载到寄存器就足矣了

对于其它复杂的数据结构也是同样的道理,无论多么复杂的数据,代码对其一次的操作都是很简单很微小的,这一微小的操作使用的基本元素都可以通过内存读写指令加载到寄存器,修改完后再写回内存。

编译器

现在你应该知道了为什么CPU内部那么少的寄存器能操作内存中庞大的数据结构,实际上由于内存中的数据要远大于CPU寄存器的容量,因此编译器必须精心挑选,好让那些经常使用的数据放到寄存器中的时间更长一点,这样可以减少内存读写次数。

在上面的示例中,r2寄存器保存的是huge_arr这个数组在内存中的起始地址,那么这个数据应该放到寄存器中,因为后续遍历到的每一个元素都要用到该地址,这项工作就是编译器来完成的。

编译器把那些经常使用的数据放到寄存器,剩下的放到内存中,然后利用内存读写指令在寄存器和内存之间来回搬运数据。

总结

通过本文不难发现,实际上我们没有必要一次性把整个数据全部装到CPU寄存器中,而是用到哪些才装载哪些。

在最细粒度的操作中,依赖的操作数都可以直接加载到内存,这通常是由内存读写机器指令来完成的。

希望这篇文章对大家理解CPU与寄存器有所帮助。

往期推荐

做安全操作系统,这位技术老兵很认真

这个高薪行业正在大量招人!

如何给女朋友解释什么是“元宇宙”?

张一鸣购得元宇宙入场券,谁将是头号玩家?

点分享

点收藏

点点赞

点在看

数据结构是如何装入 CPU 寄存器的?相关推荐

  1. PE文件-CPU寄存器-栈-常用汇编语言指令-push-move-sub-lea-rep-xor

    文章目录 1.CPU寄存器 2.常用汇编指令 3.作者答疑   如果需要对恶意软件分析,或者修改现有可执行文件的功能,如果有软件的源代码,固然可以比较好的修改,如果没有,通过汇编指令的修改亦可做到.本 ...

  2. 深入iOS系统底层之CPU寄存器介绍

    一弹指六十刹那,一刹那九百生灭. --<仁王经> 组件 计算机是一种数据处理设备,它由CPU和内存以及外部设备组成.CPU负责数据处理,内存负责存储,外部设备负责数据的输入和输出,它们之间 ...

  3. 计算机组成原理——8086 CPU寄存器

    本篇文章转载自 https://www.cnblogs.com/BoyXiao/archive/2010/11/20/1882716.html 结合文章做了一些小修改,使文章更完整. 1 总线 只是想 ...

  4. 通过 RDTSC 指令从 CPU 寄存器中直接获取系统时钟

    很多时候我们使用函数 gettimeofday 以及 clock_gettime 作为我们获取 wall lock的时钟函数. 因为这两种函数是 glibc 提供的用户封装,简单易用,而且能够精确到 ...

  5. 理解CPU/寄存器/内存三者关系

    CPU/寄存器/内存 CPU,全名Central Processing Unit(中央处理器).这是一块超大规模的集成电路,包含上亿的晶体管,是一台计算机的运算核心(Core)和控制核心(Contro ...

  6. Intel X86 CPU寄存器学习笔记

    本文对Intel CPU寄存器做一些浅显的介绍.Intel处理器寄存器在很多教科书上有,网络也有很多文章涉及到.因此本文在这些基础上做一些归纳总结,另外也参考了Intel IA32架构软件开发手册. ...

  7. CPU和CPU寄存器和CPU缓存和CPU内存管理器、RAM、hard disk。以及堆栈、内存映射。

    CPU registers cpu寄存器 包含通用寄存器,状态寄存器 Cache cpu缓存 RAM 内存 hard disk 硬盘 我们常常看到 32位 CPU.64位 CPU 这样的名称,其实指的 ...

  8. 理解CPU/寄存器/内存之间的关系

    CPU/寄存器/内存 因为要了解多线程,自然少不了一些硬件知识的科普,我没有系统学习过硬件知识,仅仅是从书上以及网络上看来的,如果有错误请指出来. CPU,全名Central Processing U ...

  9. 8086/8088 CPU寄存器组

    作者:黑剑  出处:http://www.cnblogs.com/blacksword/ 8086/8088 CPU寄存器组 今天来回顾一下8086/8088 CPU寄存器组的知识.其实8086汇编还 ...

最新文章

  1. Python如何调用matlab函数?
  2. grpc中监听端口添加及绑定
  3. 禄露禄露碌脛脥炉脛锚,学者批时下宫廷戏“就是一堆文化垃圾”
  4. C#实现人脸识别【SqlHelper】
  5. JSON数据、字符串拼接、宽字符处理、数组、Notice警告、isset和empty、变量、作用域、常量、include和require
  6. 搞笑日常:有位程序员的老爸是个什么感觉?过程你绝对意想不到!
  7. 5 种编程语言可能注定失败!
  8. 从dist到es:发一个NPM库,我蜕了一层皮
  9. 看我用ubuntu virtualbox
  10. Android Export时错误提示:Conversion to Dalvik format failed with error 1
  11. 网络安全与管理精讲视频笔记4-数字信封、数字签名、完整性验证、数据加解密及身份认证流程...
  12. 安装服务器系统驱动加载不成功,安装windows server系统提示“无法在此驱动器上安装windows”的解决办法...
  13. 超详细域名和二级域名、子域名免费配置SSL证书变成升级HTTPS(完整配置文件)
  14. Cox回归+Cox比例风险回归模型
  15. 计算机的神奇功能华为,接上线就变PC!华为Mate 10的电脑模式究竟好用不?
  16. c语言作业 分解质因数,深入分析C语言分解质因数的实现方法
  17. LCD直流数显多功能电压电流功率表电压电流表电量量产资料
  18. Win10/UWP 扫描二维码
  19. 管理系统开发的常见软件
  20. C2_W1_Lab01_Neurons_and_Layers

热门文章

  1. python炼丹师是什么_2021年编程语言趋势预测:Python和JavaScript仍火热,Go不可小觑...
  2. linux 带缓存的fwrite,文件IO编程之(六):基于流缓冲 fopen,fwrite,fput
  3. python100以内自然数之和_python教程:利用while求100内的整数和
  4. 这个省3月23日开始错时错峰开学,在校不要求戴口罩!
  5. 梅森素数为什么这么重要?
  6. 美国已批准马斯克的SpaceX发射1.2万颗卫星 以打造一个天基互联网
  7. 转行人工智能,不得不温习的数学知识点
  8. 为何美洲蝉中意17这个质数?
  9. linux双屏播放视频,Ubuntu Linux下双屏显示解决方案
  10. mysql3.5.2 下载_mybatis 3.5.2 jar 下载