3.3.3. 写入行为

在我们开始研究在多执行环境(execution context)(执行绪或行程)使用相同memory的cache行为之前,我们必须先探究一个cache实作的细节。cache是假定为一致的(coherent),而且对使用者层级的程序而言,这个一致性是假定为完全透明的。系统核心程序是不同的情况;它偶尔会要求cache冲出(flush)。

这具体意味著,假如一个cache行被修改了,在这个时间点之后,对系统而言的结果与根本没有cache、并且是主memory位置本身被修改的情况是相同的。这能以两种方式或策略来实行:

  • 直写式(write-through)cache实作;
  • 回写式(write-back)cache实作。

直写式cache是最简单的cache一致性的实行方式。若是cache行被写入的话,处理器也会立即将cache行写到主memory中。这保证了主memory与cache永远保持一致。能够在任何cache行被取代的时候直接丢弃cache的内容。这个cache策略很简单,但并不是非常快。举例来说,一支不断地修改一个区域变数的程序会在 FSB 产生大量的流量,尽管资料很可能不会在别处用到、而且可能只会短暂存在。

回写式策略更为复杂。这时处理器不会立即将被修改的cache行写回到主memory里。取而代之地,cache行只会被标记为脏的。当cache行在未来的某个时间点从cache被丢弃时,脏位(dirty bit)将会在这时通知处理器去把资料写回去,而不是直接丢弃内容。

写回式cache有机会做得好非常多,这即是大多有著像样处理器的系统中,memory都会以这种方式cache的原因了。处理器甚至能在cache行必须被清除之前,利用 FSB 的閒置容量来储存cache行的内容。这使得脏位被清除,并且在需要cache中的空间的时候,处理器能够直接丢弃这个cache行。

但回写式实作也有个重大的问题。当有多于一个处理器(或是处理器核或 HT),并且存取到同样的memory时,它仍旧必须保证每个处理器看到的一直都是相同的memory内容。假如一个cache行在一个处理器上是脏的(也就是说,它还没被写回去),并且第二个处理器试著读取相同的memory位置,这个读取操作就不能直接送到主memory去。而是需要第一个处理器的cache行的内容。在下一节,我们将会看到这在当前是如何实作的。

在此之前,还有两种cache策略要提一下:

  • 合并写入(write-combining);以及
  • 不可cache(uncacheable)

这两种策略都是用在定址空间中、并非被真正的 RAM 所支援的特殊区域。系统核心为这些地址范围设置了这些策略(在使用了memory型态范围暂存器〔Memory Type Range Register,MTRR〕的 x86 处理器上),剩下的部分自动地进行。MTRR 也能用于在直写式与回写式策略之间选择。

合并写入是一种受限的cache最佳化,更常用于显示卡一类装置上的 RAM。由于对装置来说,传输成本比区域 RAM 存取的成本还高得多,因此避免过多的传输是更为重要的。仅因为cache行中的一个字组被修改,就传输一整个cache行,在下一个操作修改了下一个字组的情况下是很浪费的。能够轻易地想像,一种常见的情况是,表示萤幕上水平相邻的像素点的memory,在多数情况下也是相邻的。如同名字所暗示的,合并写入会在cache行被写出去之前合并多个写入存取。在理想情况下,cache行会被一个字组接著一个字组地修改,并且只有在写入最后一个字组之后,cache行才会被写到装置中。这能够显著地加速装置对 RAM 的存取。

最后,不可cache的memory。这通常表示memory位置根本不被 RAM 所支援。它可能是一个被写死的特殊地址,以拥有某个在 CPU 外部实作的功能。对商用硬件来说,最常见的例子是memory对映的(memory-mapped)地址范围,转译为对附属于总线上的扩充卡以及装置(PCIe 等等)的存取。在嵌入式单板(embedded board)上,有时候会发现能够用来开关 LED 的memory地址。cache这类地址显然是个坏点子。在这种情境下的 LED 是用以除错或者状态回报的,会想要尽可能快地看到它。在 PCIe 扩充卡上的memory能够在不与 CPU 互动的情况下改变,因此这种memory不应该被cache。

results matching ""

    No results matching ""