CPU发来的访存请求可能是读(load类指令),也可能是写(store类指令)。如果是读请求的话,判断是否命中cache。如果命中了的话,便立刻返回数据。而如果缺失了,则需要从内存读取数据。再将数据写入Cache,并返回数据给CPU,这两个操作可以同时进行。如果是写请求的话,判断是否命中cache。如果缺失的话,将数据写入内存。如果命中了的话,则既需要将数据写入内存,也需要写入Cache(cache原本常用的数据变了,比如喜欢读一本书但是书的内容有更新)。
  当Cache写命中时,最简单的想法是将数据同时写入到Cache和内存。这样保证了Cache和内存中的数据都是修改后最新的数据,保持了一致性。但也导致了大量的写内存操作,因此效率非常低。而另一种想法是只写入Cache,同时标记该Cacheline为已修改,等到万不得已的时候(该cacheline被替换时)再写入内存。这可以大大减少写内存的次数。这两种策略分别为写直达和写回。
  上面讨论的是写命中的情况,当写缺失时。针对是否需要将数据写入Cache,可以分为写分配和写不分配。写不分配:写缺失的情况下,CPU直接将数据写入到内存中。写分配:在写缺失的情况下,同时将数据写入到cache跟内存中。写直达通常结合写不分配策略一起使用,即写缺失时,直接写入内存,而不写入Cache。而写回通常结合写分配策略一起使用,即写缺失时,只写入Cache,而不写入内存。
  写直达配合写不分配的策略。我们可以简单分析其性能。在读命中的情况下,CPU直接读取对应的cacheline获取数据;在读缺失的情况下,CPU直接访问内存获取数据;在写缺失的情况下,CPU直接将数据写入到内存中;在写命中的情况,CPU将数据同时写入对应的cahceline和内存中对应的地址。综上所述,也就是只有在读命中的情况下,CPU不用访问内存,但是在其他情况下,CPU都会访问内存。综上所述,也就是只有在读命中的情况下,CPU不用访问内存,但是在其他情况下,CPU都会访问内存。显然,这里还有很大的提升空间。
  对于上面的情况,一种策略就是实现写回的cache。写回给人一种不到万不得已不起床的感觉。写回策略是在写命中的情况下,并不直接将数据写入到下级存储器中,而是只将数据写入到索引到的cacheline中,当且仅当一个脏的cacheline要被替换的时候再将数据更新到内存中。写回策略一般是跟写分配策略配合的。现在稍微总结一下采用写回--写分配策略、直接映射的cache的实现:
  1.在读命中的情况下,CPU直接读取对应的cacheline的数据;
  2.在读缺失的情况,如果索引到的cacheline是干净的,那么发送读请求,从内存读取数据,然后返回给CPU,同时将数据写入到索引到的cacheline中;如果索引到的cacheline是脏的,那么首先要发送写请求,将这个cacheline的脏数据写入到内存中。等待写请求处理完成后,再发送读请求,从内存中读取对应的数据,然后再把数据返回给CPU,同时将数据写入到索引的cacheline中。
  3.在写命中的情况下,如果索引到的cacheline是干净的,那么直接将数据写入到对应的cacheline中,并且将dirty位置为1;如果索引到的cacheline是脏的,直接把数据写入到cache中。
  4.在写缺失的情况下,如果索引到的cacheline是干净的,那么将数据写入到cacheline中,覆盖掉原来的数据。如果索引到的cacheline是脏的,那么首先发送写请求,将脏的cacheline的数据更新到内存中;然后等待第一个写请求处理完成后,然后将数据写入到索引到的cacheline中,并且将脏位标志位置为1;我们可能会多次将数据写入到某个相同的地址。针对这种情况,我们可以发现,写回策略仅需要在被替换出去的时候访问内存,而写通策略每次写操作都要访问内存。所以写回--写分配的策略有助于提升cache性能。

posted on 2024-06-27 21:46  fmos  阅读(2260)  评论(0)    收藏  举报