2 内存压缩系统的硬件模型
目前由于内存压缩的思想越来越引起人们的注意市场上也出现了一些基于软件的内存压缩器。这些内存压缩器主要是通过软件对数据进行压缩,但由于访问压缩数据带来的延迟,它在系统性能方面改进并不明显,有些甚至降低了系统性能。本节介绍一种基于硬件的内存压缩系统模型。
图1是一个典型的内存压缩系统的硬件模型,包括了压缩内存、L3高速缓冲、压缩内存控制器等硬件部分。
其中压缩内存(133MHz SDRAM)包含了压缩数据。L3高速缓冲是一个共享的、32MB、4路组相联、可回写的高速缓冲,每行大小为1KB,由两倍数据率(DDR)SDRAM制定。L3高速缓冲包含了未压缩的缓冲行,由于大部分的访问都可以在L3高速缓冲中命中,因此它隐藏了访问压缩主存引起的延迟。L3高速缓冲对于存储分级体系中的上层而言就是主存,它的操作对于其它硬件,包括处理器和I/O来说都是透明的。压缩内存控制器是整个内存压缩系统的控制中心,它负责数据的压缩/解压,监控物理内存的使用情况以及实际地址到物理地址的寻址过程。
数据压缩过程是这样的:压缩内存控制将1KB的高速缓冲行压缩后写入压缩内存中,然后将它们从压缩内存中读出后解压。其压缩算法就是Lempel-Ziv算法,我们会在下一部分介绍这个算法。压缩机制将压缩的数据块以不同的长度格式存放到内存中。压缩内存的存储单元是一个256字节的区域。按照压缩比率不同,一个1KB的内存块(正好是L3每行的大小)可以占据0~4个压缩区域。
压缩内存控制器必须根据长度格式的不同将系统总线上的实际地址翻译成物理内存的中的物理地址。实际地址是出现在处理器外部总线上常规地址。篁 址用来录十压缩内存的256字节区域。实际地址空间存在于L1/L2/L3高速缓冲中,用于立即访问。而其余的内存内容部分以压缩形式存在于物理内存中。内存控制器通过查询压缩翻译表(CTT)执行从实际地址到物理地址的翻译,这个表被保留在物理内存的某个位置。图2是CTT表的格式及内存控制器的寻址模式。
每个1KB内存块的实际地址映射到CTT的一项,而CTT每项共16字节,包括四个物理区域地址,每个地址指向物理内存听一个256字节区域。对于少于120位的块,如一个全为零的块,则使用一种特殊的CTT格式,称为通用行格式。在这种格式中,压缩数据全部存放在CTT项中,代替了四个地址指针。因此,一个1KB的通用块仅占用物理内存中的16字节,其压缩比率达到64:1。
压缩内存控制器中有一系列的寄存器用于监控物理内存使用。Sectors Used Register(SUR)向操作系统报告压缩内存的使用情况。The Sectors Used Threshold Registers,SUTHR和SUTLR,用于设置内存耗尽情况的中断入口点。SUTLR寄存器是PCI中断电路INTA的入口,而SUTHR寄存器是NMI中断的入口。当SUR超过了SUTLR的值,内存控制器产生一个中断,则操作系统采取措施来阻止内存消耗。
在实际地址到物理地址的转换中,一个有用的方法是快速页操作。它允许控制器仅修改CTT项的四个指针,从而将4KB的页面内容换出或清空。快速页操作通过将与4KB页面相关的CTT项全部修改通用行格式(即全为零),从而将这4KB页面的内容全部清空。同样,一对页面可以通过交换它们相关的CTT项的区域指针来交换页面内容。由于没有大量的数据移动发生,快速页面操作速度相当快。
压缩内存控制器的压缩/解压功能是基于LempelZiv算法来进行的,因此下一节将简单介绍一下该算法的思想。
3 内存压缩算法Lempel-Ziv
绝大多数的压缩算法,包括用得特别流行的Lempel-Ziv压缩算法家庭,都是基于对原子记录(Token)字符串的完全重复检测。这个算法虽然不是最好的算法,但是,Lempel-Ziv算法强调的是算法的简单与取得高压缩率的速率,因此它还是在内存压缩中得到了广泛的应用。
Lemple-Ziv算法(简称LZ)是编码时将一个位串分成词组,然后将数据流描述成一系列的对。每个对组成一个新的词组,它包含一个数字(前一个词组的标识)和一个位(被附加到前一个词组上)。这种编码方式很庞大,可是一旦应用到适合的字符串,它就是相当有效率的编码方式。下面举例说明这种算法是如何编码的。
++表示连接(010++1=0101),U=0010001101是未被压缩的字符串。C是压缩后的字符串。P(x)表示词组数x。先看一下U=0010001101发现,它可以被写为U=0++010001101,因此得到P(1)=P(0)++0。现在继续将其写为U=0++02++0001101,可得到P(2)=P(1)++1。现在我们已经将P(2)描述为上一词组和一个新的位的组合。下一步,U=0++01++00++01101,并得到P(3)=P(1)++0。现在我们注意到,有U=0++01+00+011++01,而P(4)=011=P(2)++1,最后得到P(5)=P(1)++1。运算的步骤如表1所列。
一旦创建了表1,就有了整个编码的图表。要创建Lempel-Ziv数据流,则依照公式创建对。如果公式是P(x)=P(A)++B,则每个对为(A++B)。因此P(1)=P(0)++0变为(00++0),P(2)=P(1)++0变为(01++0),依此类推,将所有这些对连接起来,就得到了最后的字符串,结果如表2所列。这样,C就变成000011010101011,看来比U要长得多。但这里由于U的长度短,因此未能看出优势,而且包含P(0)的公式都没有压缩,所以也引起了长度增加。
Lempel-Ziv字符串的解码是很简单的,就是抓住其中的对,对照表1进行重构。
表1 编码过程
步 骤
值
公 式
U
0
-
P(0)
0010001101
1
0
P(1)=P(0)++0
0++010001101
2
01
P(2)=P(1)++1
0++01++00++01101
3
00
P(3)=P(1)++0
0++01++00++01101
4
011
P(4)=P(2)++1
0++01++00++011++01
5
01
P(5)=P(1)++1
0++01++00++011++01
表2 如何创建编码字符串
公 式
P(1)=P(0)++0
P(2)=P(1)++1
P(3)=P(1)++0
P(4)=P(2)++1
P(5)=P(1)++1
对
00++0=000
01++1=011
01++0=010
10=++1=101
01++1=011
C
000++011++010++101++011=000011010101011
4 操作系统对内存压缩的支持
在压缩内存系统中,内存大小指的是实际内存大小,它比物理内存大。在引导时,BIOS向操作系统报告的内存大小就比实际安装的物理内存要大。例如,硬件原型安装的是512MB的SDRAM,但BIOS向操作系统报告的内存大小为1GB。当应用程序数据以2:1或更高的比率压缩时,实际内存的工作方式与一般操作系统的内存工作方式是相同的。但当应用程序以未压缩数据来填充内存时(如一个zip文件不可能达到2:1的压缩比率),由于一般的OS只看到实际地址空间,因此不能意识到物理内存已经耗尽。例如,一个操作系统的实际内存为1024MB,而牧师内存为512MB。这时实际内存已经分配了600MB,系统显示还有424MB的空闲内存。但是由于已分配内存的压缩率很低,此时物理内存的耗用已经接近512MB。如果再近一步地分配内存,那么系统就会因为物理内存的耗尽而崩溃,尽管它仍然显示还有424MB的空闲内存。这种情况下,必须由操作系统提供对压缩内存进行管理的支持。
由于内存压缩是一个比较新的概念,一般的情况作系统都没有这样的机制来区分实际地址和物理地址,也不能处理“物理内存耗尽”的情况。不过,只要对操作系统内核做一些小的改动或者在操作系统之上增加一个设备驱动程序,即可达到目的。
一般来说,要从以下几方面对压缩内存进行管理。
(1)监控物理内存使用情况
通过轮询或中断法,查看物理内存的使用情况,并在物理内存耗尽前给出警告。压缩内存管理例程是通过压缩内存控制器中的一些寄存器来实现对物理内存的监控。SUR报告物理内存的使用情况,SUTHR和SUTLR用于设置中断临界值。压缩内存管理算法是基于物理内存使用的四种状态,分别为steady、acquire、danger和interrupt,其临界值的关系是mc_th_acquire[!--empirenews.page--]嵌入式系统中的内存压缩技术
2 内存压缩系统的硬件模型
目前由于内存压缩的思想越来越引起人们的注意市场上也出现了一些基于软件的内存压缩器。这些内存压缩器主要是通过软件对数据进行压缩,但由于访问压缩数据带来的延迟,它在系统性能方面改进并不明显,有些甚至降低了系统性能。本节介绍一种基于硬件的内存压缩系统模型。
图1是一个典型的内存压缩系统的硬件模型,包括了压缩内存、L3高速缓冲、压缩内存控制器等硬件部分。
其中压缩内存(133MHz SDRAM)包含了压缩数据。L3高速缓冲是一个共享的、32MB、4路组相联、可回写的高速缓冲,每行大小为1KB,由两倍数据率(DDR)SDRAM制定。L3高速缓冲包含了未压缩的缓冲行,由于大部分的访问都可以在L3高速缓冲中命中,因此它隐藏了访问压缩主存引起的延迟。L3高速缓冲对于存储分级体系中的上层而言就是主存,它的操作对于其它硬件,包括处理器和I/O来说都是透明的。压缩内存控制器是整个内存压缩系统的控制中心,它负责数据的压缩/解压,监控物理内存的使用情况以及实际地址到物理地址的寻址过程。
数据压缩过程是这样的:压缩内存控制将1KB的高速缓冲行压缩后写入压缩内存中,然后将它们从压缩内存中读出后解压。其压缩算法就是Lempel-Ziv算法,我们会在下一部分介绍这个算法。压缩机制将压缩的数据块以不同的长度格式存放到内存中。压缩内存的存储单元是一个256字节的区域。按照压缩比率不同,一个1KB的内存块(正好是L3每行的大小)可以占据0~4个压缩区域。
压缩内存控制器必须根据长度格式的不同将系统总线上的实际地址翻译成物理内存的中的物理地址。实际地址是出现在处理器外部总线上常规地址。篁 址用来录十压缩内存的256字节区域。实际地址空间存在于L1/L2/L3高速缓冲中,用于立即访问。而其余的内存内容部分以压缩形式存在于物理内存中。内存控制器通过查询压缩翻译表(CTT)执行从实际地址到物理地址的翻译,这个表被保留在物理内存的某个位置。图2是CTT表的格式及内存控制器的寻址模式。
每个1KB内存块的实际地址映射到CTT的一项,而CTT每项共16字节,包括四个物理区域地址,每个地址指向物理内存听一个256字节区域。对于少于120位的块,如一个全为零的块,则使用一种特殊的CTT格式,称为通用行格式。在这种格式中,压缩数据全部存放在CTT项中,代替了四个地址指针。因此,一个1KB的通用块仅占用物理内存中的16字节,其压缩比率达到64:1。
压缩内存控制器中有一系列的寄存器用于监控物理内存使用。Sectors Used Register(SUR)向操作系统报告压缩内存的使用情况。The Sectors Used Threshold Registers,SUTHR和SUTLR,用于设置内存耗尽情况的中断入口点。SUTLR寄存器是PCI中断电路INTA的入口,而SUTHR寄存器是NMI中断的入口。当SUR超过了SUTLR的值,内存控制器产生一个中断,则操作系统采取措施来阻止内存消耗。
在实际地址到物理地址的转换中,一个有用的方法是快速页操作。它允许控制器仅修改CTT项的四个指针,从而将4KB的页面内容换出或清空。快速页操作通过将与4KB页面相关的CTT项全部修改通用行格式(即全为零),从而将这4KB页面的内容全部清空。同样,一对页面可以通过交换它们相关的CTT项的区域指针来交换页面内容。由于没有大量的数据移动发生,快速页面操作速度相当快。
压缩内存控制器的压缩/解压功能是基于LempelZiv算法来进行的,因此下一节将简单介绍一下该算法的思想。
3 内存压缩算法Lempel-Ziv
绝大多数的压缩算法,包括用得特别流行的Lempel-Ziv压缩算法家庭,都是基于对原子记录(Token)字符串的完全重复检测。这个算法虽然不是最好的算法,但是,Lempel-Ziv算法强调的是算法的简单与取得高压缩率的速率,因此它还是在内存压缩中得到了广泛的应用。
Lemple-Ziv算法(简称LZ)是编码时将一个位串分成词组,然后将数据流描述成一系列的对。每个对组成一个新的词组,它包含一个数字(前一个词组的标识)和一个位(被附加到前一个词组上)。这种编码方式很庞大,可是一旦应用到适合的字符串,它就是相当有效率的编码方式。下面举例说明这种算法是如何编码的。
++表示连接(010++1=0101),U=0010001101是未被压缩的字符串。C是压缩后的字符串。P(x)表示词组数x。先看一下U=0010001101发现,它可以被写为U=0++010001101,因此得到P(1)=P(0)++0。现在继续将其写为U=0++02++0001101,可得到P(2)=P(1)++1。现在我们已经将P(2)描述为上一词组和一个新的位的组合。下一步,U=0++01++00++01101,并得到P(3)=P(1)++0。现在我们注意到,有U=0++01+00+011++01,而P(4)=011=P(2)++1,最后得到P(5)=P(1)++1。运算的步骤如表1所列。
一旦创建了表1,就有了整个编码的图表。要创建Lempel-Ziv数据流,则依照公式创建对。如果公式是P(x)=P(A)++B,则每个对为(A++B)。因此P(1)=P(0)++0变为(00++0),P(2)=P(1)++0变为(01++0),依此类推,将所有这些对连接起来,就得到了最后的字符串,结果如表2所列。这样,C就变成000011010101011,看来比U要长得多。但这里由于U的长度短,因此未能看出优势,而且包含P(0)的公式都没有压缩,所以也引起了长度增加。
Lempel-Ziv字符串的解码是很简单的,就是抓住其中的对,对照表1进行重构。
表1 编码过程
步 骤
值
公 式
U
0
-
P(0)
0010001101
1
0
P(1)=P(0)++0
0++010001101
2
01
P(2)=P(1)++1
0++01++00++01101
3
00
P(3)=P(1)++0
0++01++00++01101
4
011
P(4)=P(2)++1
0++01++00++011++01
5
01
P(5)=P(1)++1
0++01++00++011++01
表2 如何创建编码字符串
公 式
P(1)=P(0)++0
P(2)=P(1)++1
P(3)=P(1)++0
P(4)=P(2)++1
P(5)=P(1)++1
对
00++0=000
01++1=011
01++0=010
10=++1=101
01++1=011
C
000++011++010++101++011=000011010101011
4 操作系统对内存压缩的支持
在压缩内存系统中,内存大小指的是实际内存大小,它比物理内存大。在引导时,BIOS向操作系统报告的内存大小就比实际安装的物理内存要大。例如,硬件原型安装的是512MB的SDRAM,但BIOS向操作系统报告的内存大小为1GB。当应用程序数据以2:1或更高的比率压缩时,实际内存的工作方式与一般操作系统的内存工作方式是相同的。但当应用程序以未压缩数据来填充内存时(如一个zip文件不可能达到2:1的压缩比率),由于一般的OS只看到实际地址空间,因此不能意识到物理内存已经耗尽。例如,一个操作系统的实际内存为1024MB,而牧师内存为512MB。这时实际内存已经分配了600MB,系统显示还有424MB的空闲内存。但是由于已分配内存的压缩率很低,此时物理内存的耗用已经接近512MB。如果再近一步地分配内存,那么系统就会因为物理内存的耗尽而崩溃,尽管它仍然显示还有424MB的空闲内存。这种情况下,必须由操作系统提供对压缩内存进行管理的支持。
由于内存压缩是一个比较新的概念,一般的情况作系统都没有这样的机制来区分实际地址和物理地址,也不能处理“物理内存耗尽”的情况。不过,只要对操作系统内核做一些小的改动或者在操作系统之上增加一个设备驱动程序,即可达到目的。
一般来说,要从以下几方面对压缩内存进行管理。
(1)监控物理内存使用情况
通过轮询或中断法,查看物理内存的使用情况,并在物理内存耗尽前给出警告。压缩内存管理例程是通过压缩内存控制器中的一些寄存器来实现对物理内存的监控。SUR报告物理内存的使用情况,SUTHR和SUTLR用于设置中断临界值。压缩内存管理算法是基于物理内存使用的四种状态,分别为steady、acquire、danger和interrupt,其临界值的关系是mc_th_acquire[!--empirenews.page--]如果这篇内容对您有帮助,欢迎点赞支持!