cache:寫直達、寫回、寫分配、寫不分配

fmos發表於2024-06-27

  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效能。

相關文章