内存学习(3):DRAM的基础存储结构(存储层级、读写过程,刷新与暂存)

1 DRAM背景简介

DRAM,全称为 Dynamic Random Access Memory ,中文名是“动态随机存取存储器”。所谓“动态”是和“静态”相对应的,芯片世界里还有一种 SRAM 静态随机存取存储器的存在。

笼统地说,DRAM 的结构比 SRAM 更简单,面积占用更小,适合制作大容量的存储芯片;而 SRAM 结构复杂一些,一般使用六个晶体管,面积消耗大,但是读写速度快,而且因为 SRAM 只用到晶体管,所以在工艺上和逻辑芯片相兼容,我们可以在逻辑芯片上直接集成 SRAM 。

因为 DRAM 结构简单、面积消耗小,所以一般用 DRAM 制作逻辑芯片外的大容量存储芯片,比如内存芯片。如果学过计算机组成或微机原理的相关内容,大家一定知道内存芯片和 CPU 是分离的,CPU 通过总线访问内存芯片,从内存芯片中读取数据,而这个内存芯片就是用 DRAM 制成的。

2 DRAM基本单元(Cell)

image-20231105180419376

所谓 DRAM ,是指上图所示的一个电路,为了和 DRAM 芯片相区分,把图一的电路称作一个 cell 。图中的 CMOS 晶体管涉及到数字电路的知识。简单来说,CMOS 晶体管是一个电子开关,当给晶体管最上面的一端(称作栅极)加上电压或是取消电压,晶体管两端就可以流过电流。cell 中的小电容是存储信息的关键,小电容可以存储电荷,现在规定当电容存有电荷,cell存储比特信息“ 1 ”;当电容不存有电荷,存储比特信息“ 0 ”。

当要读取 cell 的存储值,首先打开电子开关(即晶体管),然后根据导通后的电容是否会进行充放电信息获得存储值。如果 cell 保存“ 1 ”,即电容存有电荷,那么当打开开关,电容就会放电;如果 cell 保存“ 0 ”,即电容不保存电荷,那么打开开关之后电容不会放电。

当要向 cell 中写入值,仍然先打开电子开关,然后在电子开关的另一侧施加电压。如果要写入“ 1 ”,则施加高电压,此时电流会通过晶体管向电容充电;如果要写“ 0 ”,则让电子开关另一端接地。施加电压一段时间后即可断开开关,此时 cell 已经保存好写入值,因为电容很小,所以施加电压的时间会很短。

2.1 Cell阵列

image-20231105181243973

一个 cell 只能存储一比特信息,即“ 0 ”和“ 1 ”,为了存储大量信息,需要构建起 cell 阵列。cell 阵列的视觉图如上图。可以看到每行 cell 的晶体管的栅极都是连在一起的,即都连在字线上,这意味着给字线施加电压,字线对应的一行cell都会被打开。当一行 cell 被打开,cell 电容就会向位线充放电,一行中的每个 cell 都与一条位线直接相连,读取位线的电压变化,即可知道 cell 的存储信息。

  • word line:字线(用来控制读取哪一个字,一个字是有若干个字节组成,由若干*8个位组成)。之所以叫字线,是因为给这根线通电,一行 cell 都会被打开,在计算机里八位等于一个字节,多个字节等于一个字,因此多个 cell 组合起来就是多个字,因为这根线可以打开多个字,所以叫字线
  • bit line:位线。之所以叫位线,是因为在读取信息时,每一根线上的电压波动都代表一位比特信息,一根线代表一位,所以叫做位线

2.2 Cell阵列的读取

cell 的读取依靠小电容充放电,电容充放电导致位线产生电压波动,通过读取位线电压波动即可获取信息。小电容充放电所产生的电压波动是很微弱的,充放电所造成的电压波动的时间也是很短的,因此很难直接读取充放电信息,为此 cell 阵列的读取使用到了“ sense amplifier ”,即读出放大器。

读出放大器可以捕捉到微弱的电压波动,并根据电压波动的情况在本地还原出 cell 的电容电压,而且放大器内还有锁存器,可以把还原出来的电容电压值保存起来,这样一来 cell 保存的信息就从 cell 电容转移到了放大器本地。

image-20231105182455087

每条位线都要接到一个放大器中,效果图如上。在读取 cell 行(之后也称作单元行)前,需要把每根位线都 precharge(预充电)到电容电压/供电电压最大值的一半,如果供电电压是 3 V,那么就预充电到 1.5 V。预充电完毕后打开字线,单元行中每个 cell 电容或是向位线放电,或是由位线充电。放电者位线电压上升一点,充电者位线电压下降一点。放大器可以捕捉位线上的电压波动,继而在本地还原、暂存对应 cell 电压。

在这里插入一些自己个人的理解:

  • 如果存储值为0,没有电荷,预充到1.5V后,即使电容两段电压略高于0V,也一定进行充电。
  • 如果存储值为1,存在电荷,预充到1.5V后,即使电容两段电压略低于3V,也一定进行放电。

2.3 Cell的感应放大器电路、暂存电压写回

在 DRAM 芯片中,读出放大器会把 cell 阵列分成了两半。分成两半的效果图下图。
image-20231105184718598
Cell中的感应放大器有着如下的功能:

第一个功能是感测,当cell晶体管开关打开导通后,其中存储电容向位线充电,或者位线向存储电容充电时,位线上发生的电压的微小变化。感测放大器将该位线上的电压与另一根单独的位线上提供的参考电压进行比较,并将电压差放大到极限,使得存储值可以被解析为数字1或0,这是读出感应放大器在DRAM中的主要作用。

在这里插入一些个人的理解:有关于放大器是如何捕捉微弱电压波动并还原 cell 电容电压的。实际上放大器涉及到模拟电路的知识。

问题的提出:为什么要把 cell 阵列分成两半?如何更加深刻的理解放大器的实际价值?如何获取微小的电流电压,从而实现数据的稳定放大?

首先介绍一下理想放大器,在此不妨将该读出放大器理解为理想放大器,理想放大器具有如下特征:

  • 放大倍率无限大
  • 输入阻抗无限大,可以理解为输入电流为0
  • 输出阻抗为0
  • 无限大的共模抑制比(仅对两个输入端电压的差值有反应,亦即只放大有差异的部份(即差模信号)。对于两输入信号的相同的部分(即共模信号)将完全抑制

因为放大器输入端需要同时接入两根位线,仅仅捕捉两条线路上的不同电压。一般均为输入信号和地进行比较进行放大。

但是DRAM 芯片用到的放大器将两个Cell的信息进行差分比较,是“差分感测放大器”,它在放大信号波动时需要用一个基准和待测线作“比较”,此时接到放大器上的两条位线的其中一条就是所谓的基准,这条基准线经过预充电之后,其电压恒等于供电电压的一半。

第二个功能是读出放大器还充当临时数据存储元件。也就是说,在存储单元中包含的数据值被感测和放大之后,感测放大器将继续驱动保持感测的数据值,直到DRAM阵列被预充电并准备好进行另一次存取。以这种方式,可以从感测放大器访问这一行单元中的数据,而无需对单元本身进行重复的行激活。在此可以理解为:针对于这个过程中,这一堆感测放大器形成的阵列充当了缓存整行数据的行缓冲器,将信号放大并有效的保存在自己的设备中。因此,感测放大器的阵列也被称为行缓冲器,并且设计管理策略来控制感测放大器。不同的行缓冲器管理策略规定了读出放大器阵列是将数据保留一段不确定的时间(直到下一次刷新),还是在数据被恢复到存储单元后立即将其放电。

第三个功能是恢复(或刷新),主要实现当位线上的电压被感测和放大保存完存储值之后,恢复之前存储单元的值。在读取单元行时,读取行的 cell 电容,存1的电容放电之后,原本的信息就丢失了,即原来有的电荷现在放掉了;而原来存0的电容,本来没有电荷,现在却有了电荷。这种会造成信息丢失的读取行为被称为“破坏性读出”。可以理解为:导通Cell晶体管的动作允许存储电容与位线共享其存储的电荷。在电荷共享过程发生之后,存储单元内的电压大致等于位线上的电压,并且该电压电平不能用于另一读取操作。因此,在感测和放大操作之后,感测放大器还必须将放大的电压值恢复到存储单元。具体的恢复方式是在读取时,放大器还原并暂存了单元行每个 cell 的电容电压,因此可以在输出完毕之后再把这些暂存电压写回原单元行。根据放大器锁存的所读出来的值,把各条位线分别switch开关连接到供电电压或接到地,然后 cell 电容就会根据位线电压进行充电或放电,当 cell 电容充放电结束,就可以断开字线,断开字线也就宣告本次 DRAM 读取结束。

3 DRAM的刷新

Cell电容的电容值很小,存储电荷不多,无论是充电还是放电都很快,而先进 CMOS 工艺有“电流泄漏”问题,因此即使不打开字线,cell 电容也会缓慢损失电荷,久而久之信息就丢失了。(注意这里与上文的重新写回有本质的区别,虽然操作方法类似,但是造成原因不同)解决这个问题的办法是“刷新”电容,即根据电容的旧值重新向 cell 写入数据。因为要经常动态地刷新电容,所以 DRAM 叫做动态随机存储器。

“电流泄漏”是指即使晶体管没有打开,晶体管仍然可以通过极小的电流

刷新电容如何实现的?在谈论“破坏性读出”时说过放大器可以还原并暂存 cell 信息,并把暂存的信息写回到 cell 电容,因此刷新电容也可以借助放大器。具体做法是对于每个单元行,每过一段时间就自主地进行读取,等放大器暂存好信息后就立刻写回。关于单元行的刷新时机也很有讲究,一般每 64ms 内就要对 cell 阵列进行一次全面刷新。

4 DRAM芯片的读写

前文讨论过 cell 阵列的读取,在实际应用中,不会直接把一整行数据全部读出,因为一整行数据太多,真实世界中我们往往只需要其中一个比特位,因此这一节主要谈谈实际 DRAM 芯片中单个比特的读写过程。

4.1 必须的周围逻辑

为实现单个比特的读写,必须为 cell 阵列配备一系列周围逻辑电路。下图是一个简单的示范。

image-20231105194222508

  • 行地址Buf即为“字线译码模块”
  • 蓝色模块即为“读出放大器”
  • 读出放大器下面的模块是“多到一选择器”和“一到多分配器”的集合
  • 最左边的蓝色模块依次是“行地址缓存”、“列地址缓存”。

为找到二维阵列中的某一个单元,必须给出该单元的行号/行地址和列号/列地址,行地址缓存保存一堆从地址总线上获取的行号,列地址缓存保存一堆从地址总线上获取的列号。

其中,行地址会送往“字线译码模块”。字线译码模块是一个译码器,可以把短行号译码成长的独热码,独热码会形成一串数,仅有一个为1其他全为0,仅会开启一条字线,如此可以控制打开该字线对应的单元行。单元行开启后,放大器捕捉位线上的电压波动,从而还原、暂存数据到放大器本地。

之后放大器把暂存的数据送到选择器,同时列地址也会被送到选择器,选择器根据列地址把数据中的某一位送到输出线。

输出数据之后,还要把单元行数据写回。

在上图的示范中,行地址和列地址是分别用两组总线送到 DRAM 芯片上的,这意味着 DRAM 芯片要为行地址和列地址准备两组输入口/ pin 口。而 cell 阵列越大,地址的位数就越多,当 cell 阵列很大时,准备两组输入口的代价十分昂贵,因此现代 DRAM 芯片让行地址和列地址共用一组总线,其效果图如下图。

image-20231105194609945

4.2 完整的读过程

在读取 DRAM 芯片单个比特数据时:

  1. 读取前,首先给各条位线预充电(也称为 precharge ),即把位线电压拉高到供电电压的一半,拉高到一半的目的是和 cell 电容电压形成电压差,从而在打开单元行时产生电压波动,注意,预充电完成后,就可以断开位线与预充电电源的连接,此时位线处于悬空态,电压仍然保持为供电电压的一半
  2. 开始读取,首先在地址总线上输入行地址,稍后立刻置“行地址选通”(即RAS)有效,置 RAS 有效后, DRAM 芯片就把行地址缓存下来;
  3. 缓存好行地址之后,就把行地址送入译码模块,译码模块把行地址译码成独热码,独热码的每一位都接到对应的字线,理所当然的,独热码会把其中一条字线的电压值拉高;
  4. 拉高的字线所对应的单元行被打开,即单元行的晶体管导通,单元行的各个 cell 电容和位线连通。如果 cell 保存比特信息 1,即 cell 电容的电压等于供电电压,此时 cell 电容电压高于位线电压,电容放电,位线的电压稍稍上升;如果 cell 保存比特信息 0,即 cell 电容的电压等于地电压,即 0 电压,此时位线电压高于 cell 电容电压,位线向 cell 电容充电,位线电压稍稍下降;
  5. 放大器捕捉位线上的微弱电压波动,通过“差分感测”在本地生成并暂存 cell 电容电压。举个例子,如果 cell 电容等于供电电压,那么位线电压稍稍上升,放大器比较此位线和另一条基准线的电压,通过模拟电路的反馈来放大两者的电压差,最终在本地生成一个等于供电电压的输出电压,并用锁存器把输出电压锁存下来。同理,如果 cell 电容电压等于 0,放大器最终生成等于0的输出电压,并用锁存器把 0 电压锁存下来;
  6. 放大器锁存好行数据之后,把行数据送往多到一选择器;
  7. 多到一选择器根据列地址,把单元行中的某一位送到输出线;
  8. 输出之后,还需要把放大器的数据写回到单元行,即根据放大器的锁存值把位线拉高到供电电压或是 0 电压,位线向 cell 电容充放电,充放电结束之后,就可以关闭字线;
  9. 写回数据并关闭字线之后,连接位线和预充电电源,给位线预充电到供电电压的一半,为下一次读写做好准备。

请注意,上面的过程没有提到列地址哪里来的,实际上,在行地址被缓存下来之后,外界会把地址线上的地址从行地址转换成列地址,转换成列地址之后外界会置“列地址选通”有效,然后 DRAM 会把列地址缓存起来,等到第 6 步放大器送数据过来时,列地址缓存就把列地址送到多到一选择器,参与输出比特的选择。更清楚地说,列地址的缓存发生在第 2 步之后、第 7 步之前。

以下两张是 DRAM 芯片读过程的简略信号时序图,不完全一样,但都是正确的读过程,通过结合时序图和上面的文字,相信大家能更好地理解 DRAM 读的过程。其中第一张图中色块和色块的边界代表时钟的有效边沿,相信有数字电路基础的朋友很容易 get 到这一点。注意,RAS 和 CAS 头上有一条横线,这代表它们是低电平有效信号。
image-20231105195248003
image-20231105195259859

4.3 完整的写过程

写过程和读过程有很多相似之处:

  1. 位线预充电到供电电压的一半;
  2. 输入、缓存行地址,译码行地址,开通单元行,开通单元行后位线产生电压波动,放大器捕捉电压波动并还原、暂存行数据到本地;
  3. 输入、缓存列地址,与此同时置写使能有效,并在 Data Buffer 存进写入比特,注意,Data Buffer 在读取 DRAM 时用来暂存输出比特,而在写 DRAM 时则用来暂存写入比特;
  4. 把写入比特送到一到多分配器,分配器根据列地址把写入比特送到对应的放大器中,放大器根据写入比特改写本地暂存值;
  5. 放大器根据暂存的电压值刷新单元行,刷新完毕后断开单元行的字线;
  6. 刷新完毕后,重新给位线预充电,为下一次读写做好准备。

下图是一张写过程的信号时序图,结合文字和图,可以更好地理解这个过程。

image-20231105195432558

4.4 时间消耗和行缓存

前面解读了 DRAM 读写一个比特的完整流程,现在详细说明读写过程的时间花费。

总的来说,读取一个比特的总体流程是:获得行号,译码行号,开启单元行,放大位线电压波动并暂存数据到放大器,获得列号并根据列号选择一位进行输出,写回数据,关闭字线,重新预充电。

而写一个比特的总体流程是:获得行号,译码行号,开启单元行,放大位线电压波动并暂存数据到放大器,获得列号并输入写入数据,根据列号把写入数据送到放大器并改写暂存值,写回数据,关闭字线,重新预充电。

在以上两个流程中,时间花费的大头是**“开启单元行”、“放大电压波动并暂存数据”**。

  • “开启单元行”之所以花费时间,是因为行地址译码器需要拉高一整条字线,需要拉高单元行上所有晶体管的栅极电压,而拉高这么多的栅极电压很耗时间。因为可以把这些栅极抽象成一个一个电容,拉高电容的电压,其实就是对电容充电,是需要时间的,电容越大,所需时间越长,而单元行上的所有的栅极由于是并联的,可以整体抽象成一个很大的电容, DRAM 读写选通环节就是用一根字线给这个很大的电容充电,因此时间消耗很大。如果cell阵列设计的不合理,即单元行上的 cell 数量太多,那么“开启单元行”会变得很昂贵。
  • 放大器放大电压波动并暂存数据也很消耗时间,因为放大器大部分是模拟电路,工作速度不快

通过上面的分析,我们可以推导出一个结论:在读写 DRAM 时,最好不要频繁地开启新单元行和使用放大器。由这个问题出发,回想之前设计的细节。

关键在于放大器的缓存区。前面总在说数据会被缓存到放大器本地,用术语来说,这个本地缓存叫做 row buffer ,即“行缓存”。虽然前面说的读写过程都是针对一个比特的,读写一个比特需要把一行数据全部读下来,并在操作完毕之后写回单元行,这种行为看上去很浪费资源。

但是这么做是避免每次读取一个比特都需要都要经历“开启单元行、放大、读数写数、写回”的全流程,这太浪费时间,为节省时间一次读取一行数据,同时尽可能的利用这么多数据,具体方法就是不要每读写完一个比特就把 row buffer 里的数据写回,而是先保持 row buffer 数据,等待后续指令,如果后续指令还要读写这一行的数据,那么就可以直接操作 row buffer ,而不需要开启单元行并抓取数据。下面两张图依次是“读一个比特就写回”和“保持 row buffer 并连续读一行中的多个比特”的时序图,显然第二个办法效率更高。

image-20231105200325087

image-20231105200335797

了解到上面一段的内容之后,自然而然得出总结:在允许 row buffer 长时间保持行数据的情况下,如果读写请求发生在 row buffer 保存的单元行中(这种情况称为“行命中”),那么 DRAM 的读写速度会很快,因为 DRAM 可以直接操作 row buffer ,而不需要读取新的单元行;而如果读写请求发生在 row buffer 之外的单元行中(这种情况称为“行缺失”),那么 DRAM 就要把 row buffer 写回并读取新的单元行,这样做速度会很慢。

5 DRAM系统层次

CPU 在读写数据的时候都是面向“字”的,而一个 cell 阵列一次只能读取一个比特,本部分针对现实世界中的存储芯片实际上是如何向 CPU 提供字进行说明。

5.1 bank划分

一个 cell 阵列一次可以提供一个比特,那么多个cell阵列就可以一次提供多个比特。假如CPU一次读写8个比特,那么就可以用 8 个 cell 阵列。查找cell阵列中的一个单元需要有其行号和列号,那CPU是否需要给8个cell阵列提供 8 组地址呢?不需要,8 个 cell 阵列可以共享一组行地址和列地址。共享行、列地址的一组 cell 阵列被称作一个 bank,下图展示了一个含有 8 个 cell 阵列的 bank 。它们共用行地址、列地址和地址选通、写使能,每个阵列提供一条输出线,8 个阵列最终组成 8 根输出线,可以输出 8 个比特。

image-20231105200638028

5.2 存储芯片/chip

一个 8 阵列的bank 一次读写 8 个比特,一颗存储芯片上一般含有多个 bank,下图是一颗含有 8 个 bank 的存储芯片的示意图。芯片每次读写都只针对一个 bank ,因此读写地址必须包含一个 bank 号,bank 号用于开启目标 bank,目标 bank 之外的 bank 是不工作的。

image-20231105200800045

5.3 rank和DIMM

拆过电脑的朋友知道电脑用的内存芯片都嵌在一个电路板上,把这个电路板插入内存插槽后,就可增加电脑内存。电路板加板上的芯片,这就是所谓的内存条,也称为 DIMM 条(全称 Dual-Inline-Memory-Modules ,中文名叫双列直插式存储模块)。内存条通过“内存通道”连接到内存控制器,一组可以被一个内存通道同时访问的芯片称作一个 rank 。一个 rank 中的每个芯片都共用内存通道提供的地址线、控制线和数据线,同时每个芯片都提供一组输出线,这些输出线组合起来就是内存条的输出线。

下图是一个包含 8 颗芯片的 DIMM 条。这 8 颗芯片被一个内存通道同时访问,所以它们合称为一个 rank 。有的 DIMM 条有两面,即两面都有内存芯片,这种 DIMM 条拥有两个 rank 。

image-20231105200933926

假设上图中的每个芯片都包含 8 个bank,每个 bank 都包含 8 个阵列,那么这条内存条就可以一次读写 8×8=64 比特,其中第一个 8 是指每个芯片输出 8 位(即为每一个bank是由8个阵列构成的可以一次输出8bit),第二个 8 是指这个 rank 总共有 8 颗芯片(即为上图的8个黑方块,每一个芯片都可以输出8bit),因为这 8 颗芯片被同一个内存通道访问,所以其被访问的 bank 和 bank 内的行地址、列地址都是完全一致的。下图是一个描述这个过程的简图:显然,我们在读写 8 颗芯片同一个 bank 同一个位置的 cell ,注意,图中没有显示不在工作状态的 bank。

image-20231105201403725

电脑有时候可以插入多个内存条,多个内存条有助于提升电脑的内存容量,但是未必能提高电脑的速度。电脑的速度受“内存通道”数限制,如果电脑有四个插槽,却只有一个内存通道,那么 CPU 仍然只能一次访问一个 rank ;但如果电脑有四个插槽的同时还有四个内存通道,那么 CPU 就可以一次访问四个 rank ,很显然,四并行访问明显比串行访问快,假设每个 rank 可以输出 64 比特,那么四通道就可以一次访问 4×64=256 比特,而单通道只能访问 64 比特。

平常听到的所谓x通道内存就是指电脑有 x 个内存通道,很显然,这个 x 越大越好,不过仅有通道也不够,还得为通道提供 rank ,即为电脑插上足够多的内存条。我们可以打开电脑的“任务管理器”查看自己电脑的内存插槽数。

参考文献

位、字节、字之间的关系_位,字节,字三者的关系-CSDN博客
理想运算放大器_百度百科
【DRAM存储器二】Sense Amplifier_highman110的博客-CSDN博客
深入内存/主存:解剖DRAM存储器 - 知乎
DRAM原理_哔哩哔哩_bilibili

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/181362.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

腾讯云CVM服务器购买流程_省钱入口(一步步操作)

腾讯云服务器购买流程直接在官方秒杀活动上购买比较划算,在云服务器CVM或轻量应用服务器页面自定义购买价格比较贵,但是自定义购买云服务器CPU内存带宽配置选择范围广,活动上购买只能选择固定的活动机,选择范围窄,但是…

linux中各种最新网卡2.5G网卡驱动,不同型号的网卡需要不同的驱动,整合各种网卡驱动,包括有线网卡、无线网卡、Wi-Fi热点

linux中各种最新网卡2.5G网卡驱动,不同型号的网卡需要不同的驱动,整合各种网卡驱动,包括有线网卡、无线网卡、自动安装Wi-Fi热点。 最近在做路由器二次开发,现在市面上卖的新设备,大多数都采用了2.5G网卡,…

3BHE022291R0101 PCD230A 专注于制造卓越人工智能

3BHE022291R0101 PCD230A 专注于制造卓越人工智能 BISTelligence是BISTel的一个分支,BISTel是为全球半导体和FPD制造商提供工程和软件自动化产品的领先供应商。半导体产品集团上个月被卖给了新思科技。在出售给Synopsys之后,Bisetlliegnce成立了两个部门…

WebSocket Day02 : 握手连接

前言 握手连接是WebSocket建立通信的第一步,通过客户端和服务器之间的一系列握手操作,确保了双方都支持WebSocket协议,并达成一致的通信参数。握手连接的过程包括客户端发起握手请求、服务器响应握手请求以及双方完成握手连接。完成握手连接后…

Ipswitch WS_FTP 12 安裝

Ipswitch WS.FTP.Professional.12.6.rar_免费高速下载|百度网盘-分享无限制 This works but quite difficult to figure out. It didnt allow me to replace the wsftpext.dll at 1st and had to test lots of ways how to replace it. This is how I did: 1. Follow the instr…

【qemu逃逸】D3CTF2021-d3dev

前言 题目给的是一个 docker 环境,所以起环境非常方便,但是该怎么调试呢?有无佬教教怎么在 docker 中调试? 我本来想着直接起一个环境进行调试,但是缺了好的库,所以就算了,毕竟本题也不用咋调…

3+单细胞+代谢+WGCNA+机器学习

今天给同学们分享一篇生信文章“Identification of new co-diagnostic genes for sepsis and metabolic syndrome using single-cell data analysis and machine learning algorithms”,这篇文章发表Front Genet.期刊上,影响因子为3.7。 结果解读&#x…

微服务架构——笔记(1)

微服务架构——笔记(1) 文章来源B站视频 尚硅谷SpringCloud框架开发教程(SpringCloudAlibaba微服务分布式架构丨Spring Cloud)教程 own process 独立部署 (1.微服务架构零基础理论) 叙述 马丁福勒 架构模式,倡导将单…

图片批量归类:告别混乱,实现高效文件管理

在日常生活中,我们经常需要处理大量的图片文件。这些图片可能来自于不同的设备、不同的目录,甚至不同的存储介质。随着时间的推移,这些图片文件会越来越多,管理起来也会越来越困难。如何高效地整理这些图片文件,告别混…

Bytedance揭秘OpenAI大模型: GPT-3到GPT-4进化路径

文章目录 探秘GPT-3到GPT-4进化之路1、SFT:早期GPT进化的推动者2、RLHF和SFT:编码能力提升的功臣3、代码加入预训练,对推理帮助最大4、“跷跷板”现象 论文地址项目链接Reference GPT-Fathom: Benchmarking Large Language Models to Deciphe…

大数据毕业设计选题推荐-智慧小区大数据平台-Hadoop-Spark-Hive

✨作者主页:IT研究室✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

差生文具多之(一)eBPF

前言 在问题排查过程中, 通常包含: 整体观测, 数据采集, 数据分析这几个阶段. 对于简单问题的排查, 可以跳过前两个步骤, 无需额外收集数据, 直接通过分析日志中的关键信息就可以定位根因; 而对于复杂问题的排查, 为了对应用的行为有更完整的了解, 可以通过以下形式收集更多的…

【MATLAB】基于灰狼优化算法优化BP神经网络 (GWO-BP)的数据回归预测

文章目录 效果一览文章概述订阅专栏只能获取一份代码部分源码参考资料效果一览 文章概述 【MATLAB】基于灰狼优化算法优化BP神经网络 (GWO-BP)的数据回归预测 在MATLAB中,基于灰狼优化算法优化BP神经网络(GWO-BP)进行数据回归预测的步骤如下: 数据准备:首先,将用于回归预…

深度学习_9_图片分类数据集

散装代码: import matplotlib.pyplot as plt import torch import torchvision from torch.utils import data from torchvision import transforms from d2l import torch as d2ld2l.use_svg_display()# 通过ToTensor实例将图像数据从PIL类型变换成32位浮点数格式…

城市内涝怎么预警?万宾科技内涝积水监测仪

在城市运行过程中,城市内涝问题频繁出现,影响城市管理水平的提升,也会进一步减缓城市基础设施建设。尤其近几年来,城市内涝灾害频繁出现,在沿海地区内涝所带来的安全隐患成为城市应急管理部门的心头大患。城市内涝的背…

Java 正则表达式分组匹配

前几篇文章都是简单判断是否满足匹配规则,当需要提取匹配结果时就用到分组匹配。 分组匹配 可以判断是否满足正则表达式,然后提取出子串。 有些时候电话号码是以 123-4567-8899 这样显示的,我们要判断某个字符串是这种形式的并分别提起三段…

从NetSuite Payment Link杂谈财务自动化、数字化转型

最近在进行信息化的理论学习,让我有机会跳开软件功能,用更加宏大的视野,来审视我们在哪里,我们要到哪去。 在过去20多年,我们的财务软件经历了电算化、网络化、目前处于自动化、智能化阶段。从NetSuite这几年的功能发…

【vue2高德地图api】04-poi搜索

系列文章目录 文章目录 系列文章目录前言一、高德地图文档入口二、使用步骤1.创建文件以及路由2.编写页面代码3.样式4变量以及方法5.编写查询方法 总结 前言 提示:这里可以添加本文要记录的大概内容: 本篇要实现的功能,看下图 提示&#x…

【从零开始学习Redis | 第五篇】基于布隆过滤器解决Redis的穿透问题

前言: 在如今的开发中,使用缓存中间件Redis已经成为一项很广泛的技术,Redis的高性能大大优化了我们的服务器性能,缓解了在高并发的情况下服务器的压力。它基于缓存的形式,在内存中保存数据,减少对磁盘的IO操…

制造行业数字化运维破局之道

项目背景 某大型汽车制造集团,致力于通过数字化、智能化运营手段为用户提升提供高品质的汽车产品和服务。IT部门不仅为内外部持续提供服务,同时为业务运营与核心系统运行提供重要支撑。数字化运维作为数字化转型的核心基础,不但要保障数据安…