缓存遇到写入时会发生什么

基本上访问cache的操作都是读,写占少数,而所有的指令缓存访问都是读,大多数指令不会写入到内存,所以大多数情况优化cache代表着优化cache read,特别是因为处理器传统上等待读取完成但不需要等待写入

cache读操作时,block的数据读取和tag域检验可以在同时进行,所以只要一拿到block address时就可以直接从缓存中读取数据,如果tag检验没有问题,即命中,那么缓存块会被立即传给处理器,当未命中时,直接将读取的数据丢掉

然而write操作不能这么做,只有等待tag检验没有问题后,block才能被写入,因为tag的检验无法同步进行,write相比read会花费更长时间,更复杂的是处理器一般会指定写入大小,一般都是1字节到8字节之间,只有这部分block可以被修改,相比之下,读可以接触到更多的字节

写入缓存一般有两种策略:

  1. 直写:信息被写入缓存中的块和低级内存中的块(the information is written to both the block in cache and to the block in lower-level memory)
  2. 写回:信息仅写入缓存中的块。 修改后的缓存块仅在被替换时才写入主存(the information is written only to the block in the cache. the modified cache block is written to main memory only when it is replace)

为了减少写回块替换的频率,通常使用一个脏位,脏位通常表示这个block是否dirty(cache中数据被改变)或者clean(数据没有改变),如果是clean,当遇到未命中时不会写回,因为cache跟下一级的存储是完全一样的

直写和写回都有各自的优点

一个block的多次写入只在被替换时会写入一次到低一级存储,因为一些写入不会到内存,所以写回只会占用更少的内存带宽。在多处理器中写回有其优点,因为回写使用的其余内存层次结构和内存互连少于直写,也减少能耗,在嵌入式应用更具有吸引力

直写相比于写回实现更为简单,不同于写回只在替换时写入,直写中低一级的存储一直保存最近的数据,这简化了数据同步问题,在多处理器和I/O上,数据同步很重要。多级缓存使上级缓存的写入更可行,因为写入只需要传播到下一个较低级别,而不是一直传播到主内存

在直写中处理器必须等待写入完成,处理器称这一过程位写入停顿(write stall),减少写入停顿较为常用的方法是使用写入缓冲(write buffer),当数据被写入到写入缓冲时处理器可以继续运行,从而使处理器执行与内存更新同步进行

当遇到写入未命中时,有两种选项来处理:

  1. 写入分配(Write allocate):在写入未命中时分配块,然后是前面的写入命中操作(The block is allocated on a write miss, followed by the preceding write hit actions)
  2. 无写入分配(No-write allocate):这种明显不寻常的替代方案是写入未命中不会影响缓存。 相反,该块仅在较低级别的内存中被修改(This apparently unusual alternative is write misses do not affect the cache. Instead, the block is modified only in the lower-level momory)

在程序尝试读取块之前,块在无写入分配中保持在缓存之外,但仅写入的块仍将在写入分配的缓存中(block stay out of the cache in no-write allocate until the program tries to read the blocks, but enven blocks that are only written will still be in the cache with write allocate)

上面关于这两个的解释我看的云里雾里的,这里提一下它后面的习题估计有助于理解

假如有以下五个操作,请分别说明在Write allocate和No-write allocate下的命中和未命中数
Write Mem[100];
Write Mem[100];
Read Mem[200];
Write Mem[200];
Write Mem[100];

在Write allocate情况下,第一步写入Mem[100]的操作是未命中的,第二步写入Mem[100]为命中,第三步读取Mem[200]未命中,第四步写入Mem[200]命中,第五步写入Mem[100]命中,总共是3次命中,2次未命中
在No-write allocate情况下,第一步写入Mem[100]的操作是未命中的,第二步写入Mem[100]同样未命中,因为No-write allocate不会影响缓存,第三步读取Mem[200]未命中,第四步写入Mem[200]命中,第五步写入Mem[100]未命中,总共是1次命中,4次未命中

由上面这个例题可以看出,其实简单来说,Write allocate就是在写入未命中时会将未命中的地址写入到分配块中,可以认为也是一个缓存,而No-write allocate不会有任何措施,不会影响缓存

一般回写使用Write allocate,希望接下来的写入可以在缓存中命中,直写使用No-write allocate,理由是接下来的写入本身会写入到低级存储,使用Write allocate分配的块并没有什么作用

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇
Theme Argon
本网站自 2020-12-24 12:00:00 起已运行