RM新时代网站-首页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

關(guān)于LRU(Least Recently Used)的邏輯實(shí)現(xiàn)

Spinal FPGA ? 來源:Spinal FPGA ? 2024-11-12 11:47 ? 次閱讀

湊巧看到一個(gè)有關(guān)LRU(Least Recently Used)的邏輯實(shí)現(xiàn),其采用矩陣方式進(jìn)行實(shí)現(xiàn),看起來頗有意思,但文章中只寫方法不說原理,遂來研究下。

LRU

LRU(Least Recently Used)算法是一種常用的緩存淘汰策略,其核心思想是:如果一個(gè)數(shù)據(jù)在最近一段時(shí)間內(nèi)沒有被訪問到,那么在未來它被訪問的可能性也很小。因此,當(dāng)緩存滿了的時(shí)候,最久未使用的數(shù)據(jù)會(huì)被淘汰。

LRU在Cache替換策略里還是有較大的用途的。對(duì)于一個(gè)N路組相連,當(dāng)對(duì)應(yīng)的entry滿了之后,當(dāng)有新的訪問請(qǐng)求到來后需從N個(gè)entry中挑選出一個(gè)替換entry。通過LRU可以挑選出最久沒有被使用的元素。

LRU矩陣實(shí)現(xiàn)原理

對(duì)于一個(gè)具有N個(gè)Entry空間,LRU實(shí)現(xiàn)可以采用矩陣方式實(shí)現(xiàn)。這里以四個(gè)Entry空間為例:

c58b690e-9056-11ef-a511-92fbcf53809c.jpg

對(duì)于矩陣中的元素Value[i,j](第i行第j個(gè)元素),定義如下:

1: 為1時(shí)表示元素i在j訪問之后被訪問過。

0:為0時(shí)表示元素i在j被訪問之后沒有被訪問過。

搞清楚了這兩個(gè)元素定義,那么我們自然可以定義規(guī)則。當(dāng)entry i被訪問時(shí),執(zhí)行如下操作:

將第i行所有元素全部設(shè)置為1.

將第i列所有元素全部設(shè)置為0.

這里有一個(gè)點(diǎn)就是Value[i,i]將會(huì)被設(shè)置為0,也沒有毛病,畢竟元素i在元素i被訪問之后沒有被訪問過也是對(duì)的。

那么基于此,很明顯一定存在某一行存在所有元素全為0的情況,從而也表示了其是Least Recently Used。

下圖給出了基于矩陣的LRU檢測過程:

c5af0d32-9056-11ef-a511-92fbcf53809c.jpg

Demo

基于上面的原理,下面的代碼基于SpinalHDL寫了一個(gè)簡單的Demo,包含仿真代碼:

packageLRU

importspinal.core._
importspinal.lib._

caseclass LRUUpdateRequest(entryNum: Int)extends Bundle {
val lru_state = Bits(entryNum * entryNum bits) //LRU State entryNum row,entryNum col
val lru_update_entry = UInt(log2Up(entryNum) bits)
}

caseclass LruControl(entryNum: Int)extends Component {
val io = newBundle {
val lru_state = in Bits(entryNum * entryNum bits)//LRU狀態(tài)
val lru_entry = out UInt(log2Up(entryNum)bits) //最近最少被使用

val lru_update_req = in(LRUUpdateRequest(entryNum))
val lru_update_result = out(Bits(entryNum * entryNum bits))
}
noIoPrefix()
/** *****************************************************************************************
* 計(jì)算最近最少被使用者
* 尋找矩陣中為0的行,只需找到一個(gè)即可,找最低位
* 實(shí)現(xiàn)機(jī)制:每一行做按位或,隨后取反,轉(zhuǎn)換為尋找最低位為1的位置
* ***************************************************************************************** */
val lru_row_state = io.lru_state.subdivideIn(entryNum bits).map(~_.orR).asBits()
val lru_row_state_oh = OHMasking.first(lru_row_state) //先轉(zhuǎn)換成獨(dú)熱碼
io.lru_entry := OHToUInt(lru_row_state_oh) //再轉(zhuǎn)換成二進(jìn)制
/** *****************************************************************************************
* lru更新
* 更新規(guī)則,當(dāng)更新entry i時(shí),矩陣中第i行全部填1,矩陣中第i列全部填0
* ***************************************************************************************** */
val lru_update_entry_oh = UIntToOh(io.lru_update_req.lru_update_entry) //轉(zhuǎn)換成獨(dú)熱碼
for{
rowIndex <- 0?until entryNum;
????colIndex <- 0?until entryNum
??} {
????io.lru_update_result(rowIndex * entryNum + colIndex) := Mux(
??????sel = lru_update_entry_oh(colIndex),
??????whenTrue = False,
??????whenFalse = Mux(
????????sel = lru_update_entry_oh(rowIndex),
????????whenTrue = True,
????????whenFalse = io.lru_update_req.lru_state(rowIndex * entryNum + colIndex))
????)
??}
}

import?spinal.core.sim._
import?spinal.lib.tools.BigIntToListBoolean

object LruControlApp extends App {
??SimConfig.withFstWave.compile(LruControl(4)).doSim(dut => {
var lruState = BigInt(0)

def showLruState()= {
val lru_state_boolean = BigIntToListBoolean(lruState, 16bits)
for(rowIndex <- 0?until 4) {
????????println(s"${lru_state_boolean.slice(rowIndex * 4, rowIndex * 4 + 4).map(_.toInt)}")
??????}
????}

????def updateRequest(entry: Int)?= {
??????println(s"Update Entry:${entry}")
??????dut.io.lru_update_req.lru_update_entry #= entry
??????dut.io.lru_update_req.lru_state #= lruState
??????sleep(1)
??????lruState = dut.io.lru_update_result.toBigInt
??????//show 矩陣
??????showLruState()

??????dut.io.lru_state #= lruState
??????sleep(1)
??????val lruEntry = dut.io.lru_entry.toInt
??????println(s"The Lru Entry is $lruEntry")
??????sleep(1)
????}

????showLruState()
????dut.io.lru_state #= lruState
????sleep(1)
????val lruEntry = dut.io.lru_entry.toInt
????println(s"The Lru Entry is $lruEntry")
????sleep(1)
????for?(entry <- Array(0, 1, 2, 3, 2, 3, 0, 1, 2, 0, 3)) {
??????updateRequest(entry)
????}
??})
}

對(duì)于LRU矩陣實(shí)現(xiàn),由于矩陣的存在導(dǎo)致其所需要的資源會(huì)隨著entry的增加而膨脹。實(shí)現(xiàn)一個(gè)四路組相連則需要16bit的空間用于存儲(chǔ)矩陣信息,8路就需要64bit信息了。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 仿真
    +關(guān)注

    關(guān)注

    50

    文章

    4070

    瀏覽量

    133552
  • 邏輯
    +關(guān)注

    關(guān)注

    2

    文章

    833

    瀏覽量

    29464
  • 矩陣
    +關(guān)注

    關(guān)注

    0

    文章

    423

    瀏覽量

    34528

原文標(biāo)題:一文看懂LRU(Least Recently Used)實(shí)現(xiàn)

文章出處:【微信號(hào):Spinal FPGA,微信公眾號(hào):Spinal FPGA】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    LRU緩存模塊最佳實(shí)踐

    LRULeast Recently Used)是一種緩存替換算法,它的核心思想是當(dāng)緩存滿時(shí),替換最近最少使用的數(shù)據(jù)。在實(shí)際應(yīng)用中,LRU
    的頭像 發(fā)表于 09-30 16:47 ?893次閱讀

    Redis的LRU實(shí)現(xiàn)和應(yīng)用

    在編程中,計(jì)數(shù)器是一種基本但強(qiáng)大的工具,用于跟蹤和管理數(shù)據(jù)和資源。本文將深入探討不同類型的計(jì)數(shù)器的應(yīng)用,從Redis的LRU(最近最少使用)緩存淘汰算法的實(shí)現(xiàn),到如何在內(nèi)存受限的環(huán)境中有效地使用計(jì)數(shù)器,再到普通計(jì)數(shù)器的巧妙應(yīng)用。
    的頭像 發(fā)表于 12-15 09:24 ?596次閱讀

    【原創(chuàng)】Android開發(fā)—Lru核心數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)突破緩存框架

    【原創(chuàng)】Android開發(fā)—Lru核心數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)突破緩存框架回復(fù)即可獲取下載鏈接[hide=d15]鏈接:http://pan.baidu.com/s/1c2BfjsW 密碼:bta5 更多學(xué)習(xí)資料加Q:1352716312,學(xué)習(xí)交流群:150923287[/hide]
    發(fā)表于 06-21 16:58

    關(guān)于汽車網(wǎng)絡(luò)管理邏輯環(huán)的實(shí)現(xiàn)問題

    最近想做汽車網(wǎng)絡(luò)管理,但是資料比較少,想采用底層和模型結(jié)合的方法來實(shí)現(xiàn),看論文說要建立一個(gè)關(guān)于節(jié)點(diǎn)的邏輯環(huán),用來觀察節(jié)點(diǎn)之間的通信情況。不知道這個(gè)邏輯環(huán)具體要怎么
    發(fā)表于 04-27 15:18

    用作AND/OR邏輯的數(shù)字是什么意思

    喜我正在使用spartan6-150和ISE13.3。在地圖報(bào)告文件(.mrp)中,有一個(gè)關(guān)于“切片寄存器數(shù)量”部分中“用作AND / OR邏輯的數(shù)字”的項(xiàng)目。我想知道寄存器如何用
    發(fā)表于 10-23 10:14

    如何在LUT和邏輯元件之間以及邏輯元件和邏輯單元之間進(jìn)行交換

    嗨,我目前正在對(duì)設(shè)計(jì)進(jìn)行初步分析。我正在研究關(guān)于實(shí)現(xiàn)不同功能所需資源的不同F(xiàn)PGA。我找不到一種方法來將設(shè)計(jì)使用的LUT數(shù)量相關(guān)聯(lián),并將其轉(zhuǎn)換為virtex和spartan范圍的邏輯單元格。如果可能
    發(fā)表于 01-08 10:18

    架構(gòu)設(shè)計(jì)應(yīng)用級(jí)緩存回收策略

    下。FIFO(First In First Out):先進(jìn)先出算法,即先放入緩存的先被移除。LRULeast Recently Used):最近最少算法,使用時(shí)間距離現(xiàn)在最久的那個(gè)被
    發(fā)表于 01-14 17:08

    基于修正LRU的壓縮Cache替換策略

    以優(yōu)化壓縮cache的替換策略為目標(biāo),提出一種優(yōu)化的基于修正LRU的壓縮cache替換策略MLRU-C。MLRU-C策略能利用壓縮cache中額外的tag資源,形成影子tag機(jī)制來探測并修正LRU替換策略的錯(cuò)誤
    發(fā)表于 04-15 09:51 ?36次下載

    CMOS級(jí)邏輯電路實(shí)現(xiàn)綜述

    由前面的基礎(chǔ)可知,CMOS只能實(shí)現(xiàn)基本邏輯的非,比如或邏輯,與邏輯,如果不加反相器,CMOS只能實(shí)現(xiàn)或非,與非
    的頭像 發(fā)表于 09-07 14:43 ?5738次閱讀
    CMOS級(jí)<b class='flag-5'>邏輯</b>電路<b class='flag-5'>實(shí)現(xiàn)</b>綜述

    谷歌在內(nèi)存方面依賴于per memcg lru lock

    能力。 作為世間最流行的操作系統(tǒng)Linux, 內(nèi)核使用LRU, Last Recent Used 鏈表來管理全部用戶使用的內(nèi)存,用一組鏈表串聯(lián)起一個(gè)個(gè)的內(nèi)存頁,并且使用lru lock來保護(hù)鏈表的完整性。 所有應(yīng)用程序常用操作都
    的頭像 發(fā)表于 01-15 14:00 ?1905次閱讀
    谷歌在內(nèi)存方面依賴于per memcg <b class='flag-5'>lru</b> lock

    在InnoDB如何選擇從LRU_list

    如果寫入redo 速度不變, 那么生成page 速度不變, 如果刷臟能力極其快, 那么理論上LRU_scan_depth 的深度設(shè)置成用戶每秒最大的page IO 生成能力即可, 那么系統(tǒng)最好的狀態(tài)
    的頭像 發(fā)表于 05-29 10:59 ?538次閱讀
    在InnoDB如何選擇從<b class='flag-5'>LRU</b>_list

    設(shè)計(jì)并實(shí)現(xiàn)一個(gè)滿足LRU約束的數(shù)據(jù)結(jié)構(gòu)

    LRUCache(int capacity)` 以 **「正整數(shù)」** 作為容量 `capacity` 初始化 `LRU` 緩存
    的頭像 發(fā)表于 06-07 17:05 ?997次閱讀
    設(shè)計(jì)并<b class='flag-5'>實(shí)現(xiàn)</b>一個(gè)滿足<b class='flag-5'>LRU</b>約束的數(shù)據(jù)結(jié)構(gòu)

    在組相聯(lián)cache中,用于替換cache line的算法有哪些?

    LRU(Least Recently Used)算法:該算法會(huì)跟蹤每個(gè)cache line的age(年齡)情況,并在需要時(shí)替換掉近期最少使用的cache line。
    的頭像 發(fā)表于 10-08 11:10 ?920次閱讀

    redis的淘汰策略

    的寫入。 Redis的淘汰策略主要有以下幾種: LRULeast Recently Used,最近最少使用): 這是Redis默認(rèn)的淘汰策略。當(dāng)內(nèi)存空間不足時(shí),Redis會(huì)選擇最近最
    的頭像 發(fā)表于 12-04 16:23 ?544次閱讀

    redis的lru原理

    Redis是一種基于內(nèi)存的鍵值數(shù)據(jù)庫,它使用了LRULeast Recently Used)算法來進(jìn)行緩存的數(shù)據(jù)淘汰。LRU算法的核心思想
    的頭像 發(fā)表于 12-05 09:56 ?625次閱讀
    RM新时代网站-首页