如果你觉得这是一个非常简单的问题,那么你真应该好好读读本文,我敢保证这个问题绝没有你想象的那么简单。
注意,一定要完本文,否则可能会得出错误的结论。
闲话少说,让我们来看看CPU在读写内存时底层究竟发生了什么。
谁来告诉CPU读写内存
我们第一个要搞清楚的问题是:谁来告诉CPU去读写内存?
答案很明显,是程序员,更具体的是编译器。
CPU只是按照指令按部就班的执行,机器指令从哪里来的呢?是编译器生成的,程序员通过高级语言编写程序,编译器将其翻译为机器指令,机器指令来告诉CPU去读写内存。
在精简指令集架构下会有特定的机器指令,Load/Store指令来读写内存,以x86为代表的复杂指令集架构下没有特定的访存指令。
精简指令集下,一条机器指令操作的数据必须来存放在寄存器中,不能直接操作内存数据,因此RISC下,数据必须先从内存搬运到寄存器,这就是为什么RISC下会有特定的Load/Store访存指令,明白了吧。
而x86下无此限制,一条机器指令操作的数据可以来自于寄存器也可以来自内存,因此这样一条机器指令在执行过程中会首先从内存中读取数据。
关于复杂指令集以及精简指令集你可以参考这两篇文章《CPU进化论:复杂指令集》与《不懂精简指令集还敢说自己是程序员?》
现在我们知道了,是特定的机器指令告诉CPU要去访问内存。
不过,值得注意的是,不管是RISC下特定的Load/Store指令还是x86下包含在一条指令内部的访存操作,这里读写的都是内存中的数据,除此之外还要意识到,CPU除了从内存中读写数据外,还要从内存中读取下一条要执行的机器指令。
毕竟,我们的计算设备都遵从冯诺依曼架构:程序和数据一视同仁,都可以存放在内存中。
现在,我们清楚了CPU读写内存其实是由两个因素来驱动的:
-
程序执行过程中需要读写来自内存中的数据
-
CPU需要访问内存读取下一条要执行的机器指令
然后CPU根据机器指令中包含的内存地址或者PC寄存器中下一条机器指令的地址访问内存。
这不就完了吗?有了内存地址,CPU利用硬件通路直接读内存就好了,你可能也是这样的想的。
真的是这样吗?别着急,我们接着往下看,这两节只是开胃菜,正餐才刚刚开始。
急性子吃货 VS 慢性子厨师
假设你是一个整天无所事事的吃货,整天无所事事,唯一的爱好就是找一家餐厅吃吃喝喝,由于你是职业吃货,因此吃起来非常职业,1分钟就能吃完一道菜,但这里的厨师就没有那么职业了,炒一道菜速度非常慢,大概需要1小时40分钟才能炒出一道菜,速度比你慢了100倍,如果你是这个吃货,大概率会疯掉的。
而CPU恰好就是这样一个吃货,内存就是这样一个慢吞吞的厨师,而且随着时间的推移这两者的速度差异正在越来越大: