https://zhuanlan.zhihu.com/p/86513504

平时大家都知道内存访问很快,今天来让我们来思考两个问题:

问题1: 内存访问一次延时到底是多少?你是否会进行大概的估算?

例如笔者的内存条的Speed显示是1066MHz,那是否可以推算出内存IO延时是1s/1066MHz=0.93ns? 这种算法大错特错。

问题2: 内存存在随机IO比顺序IO慢的问题吗? 我们都知道磁盘的随机IO要比顺序IO慢的多(操作系统底层还专门实现了电梯调度算法来缓解这个问题),那么内存的随机IO会比顺序IO慢吗?

要想彻底弄明白以上两个问题,我想我们得从内存IO的物理过程中来寻找答案。

先给你讲个图书管理员的故事

在开始介绍枯燥的内存工作原理之前。我想先给你讲一个故事,并带你去认识一个人,图书馆的管理员。

在我们的这个故事中,你是故事的主角。你有一所房子,房子里有一个仆人,他每天帮你处理各种各样的图书数据。但是北京房价太贵,所以你的这个房子很小,只能放的下64本书。你家的马路对面,就是北京图书馆(你家房子虽然小但是地段还不错),你所需要的所有的图书在那里都可以找到。图书馆有个管理员,他负责帮你把你想要的书找出来。

图1 图书管理员的故事

好接下来,故事开始进行!

场景1:

你发现你需要编号为0的书的计算结果,你的仆人穿过马路告诉了图书管理员,告诉他请帮我把第0-63本书取出来。图书管理员帮你在电脑前查得该书在二楼。 于是他,花了点时间坐电梯到了二楼。等到了二楼,他又花了点时间帮你找了出来。然后你的仆人抱着64本书放到了客厅,拿起第0本书帮你处理了起来。

场景2:

你发现你需要编号为1的书的计算结果,告诉你的仆人。你的仆人直接从客厅拿出来就可以处理了,这次你等的时间最短。

场景3:

你发现需要编号为65的书,你又告诉你的仆人。你的仆人穿过马路又去找了图书管理员。图书管理员还在二楼呢,听说这次需要65-127,这次他不用再花时间找楼层了。只是花时间找书就可以了。你的仆人把65-127的书放到了客厅(以前的0-63就都扔了),并帮你开始处理起65号书来。

场景4:

你发现你需要编号为10000的书,你告诉了你的仆人。你的仆人穿过马路去图书馆,找到了管理员。这次管理员查得你需要的书是在10楼,他得花点时间坐电梯过去。去了之后,他又得花点时间帮你找出来。

这四个场景里,我觉得你一定发现了不同情形下耗时的差异。

  • 场景1和场景4花费的时间最多。因为图书管理员需要花时间坐电梯找楼层,需要花时间在楼内找书。
  • 场景3次之,因为图书管理员直接就在楼层内,只需要花时间在楼内找书既可
  • 场景2最快,因为只需要仆人帮你从客厅拿过来就好,连马路都不需要过。

之所以编造这么一个例子,是因为内存的工作方式和它太像了。 接下来我们进入内存的实际分析。

内存的物理结构

《带你理解内存对齐最底层原理!》中我们了解了内存颗粒的物理构造以及IO过程,今天我们再来复习一下。

内存是由chip构成。每个chip内部,是由8个bank组成的。其构造如下图:

图2 内存颗粒chip内部结构

而每一个bank是一个二维平面上的矩阵,前面文章中我们说到过。矩阵中每一个元素中都是保存了1个字节,也就是8个bit。

图3 bank内部物理结构

每当CPU向内存请求数据的时候,内存芯片总是8个bank并行一起工作。每个bank在定位到行地址后,把对应的行copy到row buffer。 再根据列地址把对应的元素中的数据取出来,8个bank把数据拼接一下,一个64位宽的数据就可以返回给CPU了。

图4 一次内存IO的过程示意

根据上面几张图我们可以大致了解内存的IO过程,在这个过程中每一步操作之间都有一些延迟,让我们来继续了解这些延迟。

内存IO延迟

《从DDR发展到DDR4,内存核心频率指标其实基本上就没太大的进步》里我们提到内存的延迟很大程度是受核心频率制约的,你也应该记得我们提到了内存延迟一般是通过CL-tRCD-tRP-tRAS四个参数来标识的。 我们今天来详细理解一下这四个参数的含义:

  • CL(Column Address Latency):发送一个列地址到内存与数据开始响应之间的周期数
  • tRCD(Row Address to Column Address Delay):打开一行内存并访问其中的列所需的最小时钟周期数
  • tRP(Row Precharge Time):发出预充电命令与打开下一行之间所需的最小时钟周期数。
  • tRAS(Row Active Time):行活动命令与发出预充电命令之间所需的最小时钟周期数。也就是对下一次预充电时间进行限制。

要注意除了CL是固定周期数以外,其它的三个都是最小周期。另外上面的参数都是以时钟周期为单位的。因为现代的内存都是一个时钟周期上下沿分别各传输一次数据,所以用Speed/2就可以得出,例如笔者的机器的Speed是1066MHz,则时钟周期为533MHz。你自己的机器可以通过dmidecode命令查看:

# dmidecode | grep -P -A16 "Memory Device"
Memory Device
......
Speed: 1067 MHz
......

和“图书管理员”类似,内存芯片也有类似的工作场景:

场景1:

你的进程需要内存地址0x0000为的一个字节的数据,CPU这时候向内存控制器发出请求,内存控制器进行行地址的预充电,需要等待tRP个时钟周期。再发出打开一行内存的命令,又需要等待tRCD个时钟周期。接着发送列地址,再等待CL个周期。最终将0x0000-0x0007的数据全部返回给了CPU。 CPU把这些数据放入到了自己的cache里,并帮你开始对0x0000的数据进行运算。

场景2:

你的进程需要内存地址0x0003的一个字节数据,CPU发现发现它在自己的cache里存在,直接使用就好了。这个场景里其实根本就没有内存IO发生。

场景3:

你的进程需要内存地址0x0008的一个字节数据,CPU的cache并没有命中,于是向内存控制器请求。内存控制器发现行地址和上一次工作的行地址一致,这次只需要发送列地址后等待CL个周期,就可以拿到0x0008-0x0015的数据并返回给CPU了。

场景4:

你的进程需要内存地址0xf000的一个字节数据,同样CPU的cache并不命中,向内存控制器请求。内存控制器一看(内心有些许的郁闷),这次行地址又变了,得,和场景1一样。继续等待tRP+tRCD+CL个周期后,才能够取到数据并返回。

实际的计算机的内存IO过程中还需要进行逻辑地址和物理地址的转换,这里忽略不表。

结论

其中场景1和场景4是随机IO的情况,场景2无内存IO发生,场景3是顺序IO。通过上面的过程描述我们可以得到结论。内存也存在和磁盘一样,随机IO比顺序IO要慢的问题。如果行地址同上一次访问的不一致,则需要重新拷贝row buffer,延迟周期需要tRP+tRCD+CL。而如果是顺序IO的话(行地址不变),只需要CL个周期既可完成。

我们接着估算下内存的延时,笔者的机器上的内存参数Speed为1066MHz(通过dmidecode查得),该值除以2就是时钟周期的频率=1066/2=533Mhz。其延迟周期为7-7-7-24。

  • 随机IO:这种状况下需要tRP+tRCD+CL个时钟周期,7+7+7=21个周期。但是还有个tRAS的限制,两次行地址预充电不得小于24。所以我们得按24来计算,24*(1s/533Mhz) = 45ns
  • 顺序IO:这种状况下只需要CL个时钟周期 7*(1s/533Mhz)=13ns

扩展:回顾CPU的Cache Line

因为对于内存来说,随机IO一次开销比顺序IO高好几倍。所以操作系统在工作的时候,会尽量让内存通过顺序IO的方式来进行。做法关键就是Cache Line。当CPU发现缓存不命中的时候,实际上从来不会向内存去请求1个字节,8个字节这种。而是一次性就要64字节,然后放到自己的Cache中存起来。

用上面的例子来看,

  • 如果随机请求8字节:耗时是45ns
  • 如果随机请求64字节:耗时是45+7*13 = 136ns

开销也没贵多少,因为只有第一个字节可能是随机IO,后面的7个字节都是顺序IO。数据是8倍,但是IO耗时只有3倍,而且取出来的数据后面大概率要用,所以计算机内部就这么搞了,通过这种方式帮你避免一些随机IO!

另外,内存也支持burst(突发传输)模式,在这种模式下可以只传入一次行列地址,就命令内存返回该内存开头的连续字节数据,比如64字节。这种模式下,只有第一次的8字节需要真正的行列访问延迟,后面的7个字节可以直接按内存的数据频率给吐出来。接下来我们进行实践测试,请转移到《实际测试内存在顺序IO和随机IO时的访问延时差异》

[转帖]内存随机访问也比顺序慢,带你深入理解内存IO过程的更多相关文章

  1. 关于顺序磁盘IO比内存随机IO快的讨论

    这个问题来源于我书中引用的一幅图: 我们从图中明显可以看某性能测试的结果表明普通机械磁盘的顺序I/O性能指标是53.2M values/s,SSD的顺序I/O性能指标是42.2M values/s,而 ...

  2. Java API —— IO流(数据操作流 & 内存操作流 & 打印流 & 标准输入输出流 & 随机访问流 & 合并流 & 序列化流 & Properties & NIO)

    1.操作基本数据类型的流     1) 操作基本数据类型 · DataInputStream:数据输入流允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型.应用程序可以使用数据输出 ...

  3. Java内存模型深度解析:顺序一致性--转

    原文地址:http://www.codeceo.com/article/java-memory-3.html 数据竞争与顺序一致性保证 当程序未正确同步时,就会存在数据竞争.java内存模型规范对数据 ...

  4. Java:IO流其他类(字节数组流、字符数组流、数据流、打印流、Properities、对象流、管道流、随机访问、序列流、字符串读写流)

    一.字节数组流: 类 ByteArrayInputStream:在构造函数的时候,需要接受数据源,而且数据源是一个字节数组. 包含一个内部缓冲区,该缓冲区包含从流中读取的字节.内部计数器跟踪 read ...

  5. 深入理解Java内存模型(三)——顺序一致性

    数据竞争与顺序一致性保证 当程序未正确同步时,就会存在数据竞争.java内存模型规范对数据竞争的定义如下: 在一个线程中写一个变量, 在另一个线程读同一个变量, 而且写和读没有通过同步来排序. 当代码 ...

  6. MappedByteBuffer高速缓存文件、RandomAccessFile随机访问

    说到高速缓存存储,处理读写文件,那就不得不说MappedByteBuffer. 看了好多文章以后写一下自己的总结. 在这里先介绍一下相关的类与方法. 先说一下Buffer.ByteBuffer.Map ...

  7. 【转】深入理解Java内存模型(三)——顺序一致性

    数据竞争与顺序一致性保证 当程序未正确同步时,就会存在数据竞争.java内存模型规范对数据竞争的定义如下: 在一个线程中写一个变量, 在另一个线程读同一个变量, 而且写和读没有通过同步来排序. 当代码 ...

  8. Java IO详解(六)------随机访问文件流

    File 类的介绍:http://www.cnblogs.com/ysocean/p/6851878.html Java IO 流的分类介绍:http://www.cnblogs.com/ysocea ...

  9. Java开发笔记(八十七)随机访问文件的读写

    前面介绍了字符流读写文件的两种方式,包括文件字符流和缓存字符流,但是它们的写操作都存在一个问题:不管是write方法还是append方法,都只能从文件开头写入,而不能追加到文件末尾或者在文件中间某个位 ...

  10. Java IO详解(七)------随机访问文件流

    File 类的介绍:http://www.cnblogs.com/ysocean/p/6851878.html Java IO 流的分类介绍:http://www.cnblogs.com/ysocea ...

随机推荐

  1. 作为所有类的顶层父类,没想到Object的魔力如此之大!

    写在开头 在上一篇博文中我们提到了Java面向对象的四大特性,其中谈及"抽象"特性时做了一个引子,引出今天的主人公Object,作为所有类的顶级父类,Object被视为是James ...

  2. Cesium渲染一帧中用到的图形技术

    译者注:本文翻译自Cesium官方博文<Graphics Tech in Cesium - Rendering a Frame>,May 14, 2015 by Patrick Cozzi ...

  3. 什么是HuggingFace

    一.HuggingFace简介 1.HuggingFace是什么 可以理解为对于AI开发者的GitHub,提供了模型.数据集(文本|图像|音频|视频).类库(比如transformers|peft|a ...

  4. 实证与虚无,抽象和具象,Go lang1.18入门精炼教程,由白丁入鸿儒,Go lang接口(interface)的使用EP08

    看到接口这两个字,我们一定会联想到面向接口编程.说白了就是接口指定执行对象的具体行为,也就是接口表示让执行对象具体应该做什么,所以,普遍意义上讲,接口是抽象的,而实际执行行为,则是具象的. 接口(in ...

  5. 【API 进阶之路】做 OCR 文字识别,谁说必须要有 AI 工程师?

    摘要:有些功能还真不能光凭自己的直觉和认识,来自一线的声音才是最真实的用户需求.比方说名片录入的需求. 在公司技术委员会副主席这个位置上干了有几个月了,期间,我一方面给研发团队整理各种文档资料,做技术 ...

  6. 【DevCloud · 敏捷智库】暴走在发布前夜的开发,你怕不怕?

    摘要:每个月都有2天开发团队要通宵熬夜,大家苦不堪言.有个别的开发同学,骂完公司骂同事,骂完同事骂客户的,甚至连自己都不放过-- 来自一个CEO的叙述 在一次企业交流会上,一个公司的CEO提道,&qu ...

  7. CodeLab:一款让你体验丝滑般的云化JupyterLab

    摘要:从AI开发特点着手,华为云AI DTSE技术布道师陈阳在DTT第五期带来主题为<云化JupyterLab:华为云CodeLab介绍>技术分享. DTSE Tech Talk是华为云开 ...

  8. 数字化转型鸿沟如何消除?ROMA Connect融合集成,联接企业应用现在与未来

    摘要:ROMA Connect平台正在以"联接和融合"的方式,重塑传统企业上云的路径--"条条大路"通向云端. 本文分享自华为云社区<[大厂内参]第13期 ...

  9. 被灵魂问倒:这个BUG为什么没测出来?

    摘要:为什么没测出来!测试怎么测得?到底会不会测?这对测试来说是灵魂拷问级别不好回答的问题了. 本文分享自华为云社区<被问:这个BUG为什么没测出来?该如何回答>,作者: 曲鸟. 一.前言 ...

  10. 8个方法管理 GitHub 用户权限

    如同世界正在经历的疫情,由于网络攻击的大幅增加,许多公司也遭受着"网络疫情",保障代码安全迫在眉睫.在之前的文章中我们了解了安全使用 GitHub 的21条最佳实践.阅读本文,将带 ...