前言
内存(Memory)是计算机的重要部件,用于存储数据和指令的重要组件,是冯诺依曼计算机中是的存储器部分。作为与CPU进行沟通的桥梁,内存用于临时存储计CPU中的运算数据,以及与硬盘、网卡等外部组件数据,以便CPU能够快速访问和处理这些信息。计算机中所有程序的运行都在内存中进行,内存性能的强弱影响计算机整体发挥的水平。
在正文开始前,让我们先思考以下几个问题:
- 3000MHz的内存频率,难道能媲美CPU的频率?
- 内存的读写速度有多快,传输带宽多少?时间级别是多少?
- Redis声称吞吐量可达到 10W/每秒,对内存来说有压力吗?
内存简介
存储器可以分为易失性存储器和非易失性存储器。易失性存储器指的是当电源关闭时会丢失其中存储的数据,典型的例子是RAM。非易失性存储器则是在断电后能够保持其中存储的数据,典型的例子包括硬盘驱动器、固态硬盘和闪存存储器,具体分类如图1所示。
本文主要讨论的是RAM和CPU的三级缓存。RAM是指计算机中的主要内存,用于存储正在运行的程序和数据;Cache是位于CPU和内存之间的高速缓存,用于临时存储CPU需要频繁访问的数据,以提高数据访问速度。
内存的基本结构
内存通常由许多存储单元组成,每个存储单元都有一个唯一的行列地址,可以存储一个字节的数据。通过这种结构,计算机可以根据地址快速地读取或写入数据。内存跟我们平常用的表格很像,最小的存储单元为cell,相当于表格中的一个小格子,具有行列地址,可以存储1bit数据(0或1)。行列的所有格子组成的存储阵列成为bank,一块内存内部划分出多个bank, 访问的时候指定bank编号,就可以访问指定的bank。
内存操作流程
CPU 对内存的操作通常包括地址计算、发起内存请求、内存访问、数据传输等步骤,这些步骤构成了 CPU 对内存进行读取和写入操作时的基本流程。 CPU 通过这些步骤与内存进行通信,实现了对数据的读取和存储。
- 地址计算:CPU 根据指令中提供的内存地址以及当前的地址计算方式(例如基址寻址、相对寻址等),计算将要读取或写入的内存地址。
- 发起内存请求:CPU 通过总线系统将内存地址发送到内存控制器,请求对应内存位置的数据读取或写入。
- 内存访问:内存控制器接收到CPU 的请求后,根据请求的地址进行相应的读取或写入操作。
- 数据传输:内存控制器从内存中读取需要的数据,或者将CPU 提供的数据写入内存中,并通过总线系统将数据传输回到 CPU。
内存参数
图4为内存的的详情页,比起CPU的参数,内存条的参数少了很多,只有容量、频率、时序。
内存性能可以通过以下指标来衡量:
- 带宽(Bandwidth):内存带宽指的是内存模块与CPU 或其他组件之间传输数据的速度。它通常以每秒传输的数据量(如GB/s)来衡量。
- 延迟(Latency):内存延迟是指从发出读取请求到数据实际可用之间的时间间隔。较低的延迟意味着内存可以更快地响应请求。
- 时序(Timing):内存时序指的是内存芯片在读取或写入数据时的精确时序要求,如CL(CAS Latency)、tRCD、tRP 等参数。
- 容量(Capacity):内存容量指内存模块可以存储的数据量,通常以GB为单位。
- 稳定性(Reliability):内存模块的稳定性指其在长时间稳定运行时不发生错误或故障的能力。
容量
容量的大小,直接影响计算机同时执行的进程数。在内存不足的时候,内存可以临时转换为硬盘的数据,在Linux为swap,在window是为虚拟缓存,因此,我们可以使用超过物理内存的大小,但硬盘的速度跟内存不是一个量级,可能会导致计算机卡顿,我们后边会有对应的文章来分析。
内存频率
内存频率是内存模块的工作频率,通常以MHz或GHz为单位。它表示内存模块每秒钟能够完成的数据传输次数。内存频率越高,内存模块的数据传输速度越快。
内存频率可以细分为核心频率、倍增频率、 有效评率、IO频率。
- 核心频率:内存电路的震荡频率,真实运行的频率,受物理材料的极限限制,核心频率的提升比较困难。
- 倍增频率:DDR(Double Data Rate)通过数据预读取技术放大速率。ddr=2,ddr2=4,ddr3=8,ddr4=8,ddr5=16.
- 等效频率:商品一般标的就是这个频率,数据的传输频率。
- IO频率:又叫时钟频率,是等效频率的一半。
我们从一些测试软件,以及系统自带的性能检测看的频率,指的是数据的传输频率,这个频率也称等效频率,也是我们在商品详情页面看的那个数值。内存频率跟CPU频率类似,CPU分为外频和倍频,内存分为核心频率和倍频。我们日常所有的内存频率=核心频率 X 倍增系数。
如图5是DDR各代频率的情况,从DDR到DDR5的内存的核心频率对比,我们可以发现核心频率一直在100MHz~400MHz之间徘徊,已经多年没有重大突破。我们所看到的内存频率是在这个核心频率的基础上,通过各种技术手段放大出来的(倍频)。之所以我们感觉内存在越来越快,就是放大技术手段在不断进步而已。
内存时序
内存时序是指内存模块在完成特定操作时所需的时间周期。它通常由一系列数字表示,包括CL、tRCD、tRP、tRAS等,如图6所示。这些数字描述了内存模块在执行读取和写入操作时的速度和延迟。较低的时序值通常表示内存模块能够更快地执行操作。
内存时序的具体含义如下:
- tCL(CAS延迟):指内存模块响应处理器请求的时间,数值越低表示内存响应速度越快。
- tRCD(RAS到CAS延迟):指在行地址选通后,需要多长时间才能选通列地址,数值越低表示内存响应速度越快。
- tRP(行预充电延迟):指在关闭一行后,再次打开另一行所需的时间,数值越低表示内存响应速度越快。
- tRAS(行地址选择延迟):指内存模块保持打开状态的行所需的时间,数值越低表示内存响应速度越快。
这些时序参数直接影响内存模块的访问速度和性能,较低的时序数值通常表示内存模块能够更快地执行读取和写入操作。
性能指标
了解了内存的频率和时序,我们就可以计算出内存的带宽和延迟了。以我本机的内存为例,参数:DDR4 3000MHz (8G+8G 组成双通道)
带宽 = 有效频率 X 通道数 X 单条通道位宽(bit)/ 8
3000Mhz * 2 * 64 / 8=48000MB/s
计算延迟我们,以操作中最频繁的tCL为主来计算
延迟 = 所需时间周期 / IO频率
17 / 3000Mhz / 2=11.33ns
我们通过AID64 对内存性能基准测试,结果如图8所示,从结果我们可以得知,内存的读写拷贝操作的带宽为40GB/s上下,延迟在60ns左右;而cpu的三级缓存不论是带宽还是延迟都全面碾压内存的性能。
通过对比计算的结果,我们可以看到,带宽的实际值比理论值略小,延迟的实际值比理论值大大很多。通过上边的内存工作原理,所以也很好理解,CL只是众多操作中最频繁的一个。在实际中操作中,会受到众多的元素影响,如数据刷新、信号放大、地址转换等,这些都是需要一定的时钟周期。
性能测试
我们通过实际代码来测试内存的延迟情况。
public class MemoryLatencyTest {
public static void main(String[] args) {
long startTime, endTime;
long[] memoryArray = new long[64 * 1024 * 1024];
int length = memoryArray.length;
for (int i = 0; i < length; i++) {
memoryArray[i] = i;
}
long iterations = 10000000000L;
int randomIndex;
long value = 0;
startTime = System.nanoTime();
for (long i = 0; i < iterations; i++) {
randomIndex = (int) (Math.random() * length);
value = memoryArray[randomIndex];
}
endTime = System.nanoTime();
System.out.println(value);
long averageLatency = (endTime - startTime) / iterations;
System.out.println("平均延时: " + averageLatency + " ns");
}
}
循环次数 | 平均延迟(ns) |
---|---|
100000 | 113 |
1000000 | 94 |
10000000 | 99 |
100000000 | 90 |
1000000000 | 92 |
10000000000 | 99 |
在这个示例中,我们创建了一个long类型的数组这样可以更好地控制内存访问,占用内存大于CPU的三级缓存(8M),降低CPU三级缓存的影响。对比理论值、专业软件测试、实际代码测试,有一定的差距,这是因为测量内存延迟时间要完全并避免CPU缓存影响是一个复杂的任务,需要深入了解硬件和Java运行时环境的工作原理。即使如此,我们也可以知道内存的延迟时间大概在哪个级别了。
总结
综上,我们来回答开头的问题。
- 3000MHz的内存频率,难道能媲美CPU的频率?
内存3000MHz 是指有效频率,由核心频率和倍频计算得出,而内存的核心频率只有100-400MHz,倍频是为了降低内存影响CPU多核性能。CPU标准的频率是外频和倍频计算的出,是CPU实际的频率,外频是为了适配外设。 - 内存的读写速度有多快,时间级别是多少?
CPU的的第一二级缓存的时间级别是1纳秒级别,第三级缓存是10纳秒级别,内存的时间级别则为100纳秒; - Redis声称吞吐量可达到 10W/每秒,对内存来说有压力吗?
没有压力,主要的瓶颈在网络、IO,不在内存。内存的理论远大于10W,在CPU的三级缓存加持下,性能会更加炸裂。