LSU(Load Store Unit)是一個專門的執行單元,負責執行所有的加載(load)和存儲(store)指令等,生成load和store操作的虛擬地址,并從內存中加載數據或將數據從寄存器中存儲回內存。LSU里一般包括L1 D-cache、D-TLB、AGU、load queue、store queue等模塊。
下文以(Berkeley out-of-order machine(BOOM)為例子)
- 負責決定什么時候將memory operations送到memory system;
- load instruction產生uopLD, 會計算出將要訪問的地址,并將結果存在LDQ中;
- store instruction會產生兩個微指令,uopSTA(store addr generation)和u哦怕STD(store data generation)
- STA: 計算store的地址,同時將地址存放在STQ中;
- STD:將store data存入STQ中;
- uopLD/STA/STD都是亂序進行的;
?
?Store Instructions
- 在decode stage, 會申請store queue entry; (stq[i].valid = 1);
- 每個valid bit對應兩個其他的valid, 分別是
- valid addr(stq[i].bits.addr.valid);
- valid data(stq[i].bits.data.valid);
- 當store instruction提交了,則對應的store queue中的entry也被標記成commited, 可以在合適的時候,將其釋放掉;
- store queue中的entry, 是按照PO的順序,給到memory系統中;
Store Micro-Op
- store是作為一條單獨的指令插入到issue window中;而不是被分解為單獨的addr-gen和data-gen UOP);
- 這樣做的好處是不會浪費昂貴的issue window entries, 也不會給送往LSU的issue ports帶來額外的競爭問題;
- 兩個操作數都準備好的存儲可以作為一個UOP發送給LSU, UOP同時向LSU提供地址和數據。
- 雖然這要求存儲指令能夠訪問兩個寄存器文件的讀端口,但這樣做是為了不讓store-heavy code的性能降低一半。
- Sequences involving stores to the stack should operate at IPC=1!
- 然而,通常在store addr知曉之前,就知道store addr。
- store addr應該盡快放到STQ,可以使得后續進來的load, 能夠進行沖突檢查,以避免任何內存排序失敗。
- 因此,issue windows會根據需要發出uopSTA或uopSTD UOP s,然后等待第二個操作數準備好。
Load Instructions
- 在decode stage申請LDQ entry;
- 在decode stage,每個load entry會帶一個store mask信息,ldq[i].bits.st_dep_mask, 這個標志記錄了當前這條load, 依賴于STQ中的哪些store?instruction;
- 當store fired to memory,and leaves the Store Queue, 對應的mask標志被清除;
- 當load對應的地址被計算出來,放入LDQ后,ldq[i].addr.valid =1;
- load指令在LDQ中的執行過程:
- load inst到達LSU后,會盡快的送到memory system中;
- 這樣的做法,對于亂序pipeline有巨大的好處;
- load指令,會和store queue中的entry, 進行地址比較,檢查是否依賴于store addr;
- 如果match, 則memory request會被kill掉;
- 如果對應的store data已經存在,在store data會forwarded to load,load標記為完成;
- 如過對應的store data不存在,則load會sleep, 稍后會再次進行訪問memory的申請;
?
?The BOOM Memory Model
- 遵循RVWMO memory consistency model;
- Write -> Read constraint is relaxed (newer loads may execute before older stores).
- Read -> Read constraint is maintained (loads to the same address appear in order).
- A thread can read its own writes early.
- ordering loads to the same addr;
- RVWMO要求,loads to the same addr should be orded;
- 這就要求,每個load,需要和其他的load做檢查,看是否有沖突的地址;
- 如果younger load在older load之前已經執行,則younger load將會被replay, 其后面的指令,也要在pipeline中被flush掉;
- 這種場景,出現在當memory coherence的snoop,能夠探測到core‘s memory時,并將這種reorder暴露給其他的threads時,需要處理,否則,這種reoder也是ok的;
Memory Ordering Failures?
?考慮如下的場景:
? ??
- 如果X2和X4的物理地址相同,那么load實際上應該是依賴于之前的store; 如果load先執行,那么就會讀到錯誤的數據,此時稱之為發生了memory ordering failure;
- 一旦發生了memory ordering failure,則pipeline必須flush, RAT也要重置,這是相當expensive 的operation;