Skip to content

Commit 686cede

Browse files
committed
Adopt 2-entry direct-mapped page cache
Replace the previous 1-entry direct-mapped design with a 2-entry direct-mapped cache using hash-based indexing (same parity hash as cache_load). This allows two hot virtual pages to coexist without thrashing. Measurement shows that the number of virtual-to-physical translations during instruction fetch (mmu_translate() calls) decreased by ~10%.
1 parent 74e3b99 commit 686cede

File tree

2 files changed

+10
-7
lines changed

2 files changed

+10
-7
lines changed

riscv.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,8 @@ static inline void ic_invalidate_all(hart_t *vm)
190190

191191
void mmu_invalidate(hart_t *vm)
192192
{
193-
vm->cache_fetch.n_pages = 0xFFFFFFFF;
193+
vm->cache_fetch[0].n_pages = 0xFFFFFFFF;
194+
vm->cache_fetch[1].n_pages = 0xFFFFFFFF;
194195
vm->cache_load[0].n_pages = 0xFFFFFFFF;
195196
vm->cache_load[1].n_pages = 0xFFFFFFFF;
196197
vm->cache_store.n_pages = 0xFFFFFFFF;
@@ -328,7 +329,8 @@ static void mmu_fetch(hart_t *vm, uint32_t addr, uint32_t *value)
328329

329330
/* cache miss, Continue using the original va->pa*/
330331
uint32_t vpn = addr >> RV_PAGE_SHIFT;
331-
if (unlikely(vpn != vm->cache_fetch.n_pages)) {
332+
uint32_t index = __builtin_parity(vpn) & 0x1;
333+
if (unlikely(vpn != vm->cache_fetch[index].n_pages)) {
332334
mmu_translate(vm, &addr, (1 << 3), (1 << 6), false, RV_EXC_FETCH_FAULT,
333335
RV_EXC_FETCH_PFAULT);
334336
if (vm->error)
@@ -337,15 +339,16 @@ static void mmu_fetch(hart_t *vm, uint32_t addr, uint32_t *value)
337339
vm->mem_fetch(vm, addr >> RV_PAGE_SHIFT, &page_addr);
338340
if (vm->error)
339341
return;
340-
vm->cache_fetch.n_pages = vpn;
341-
vm->cache_fetch.page_addr = page_addr;
342+
vm->cache_fetch[index].n_pages = vpn;
343+
vm->cache_fetch[index].page_addr = page_addr;
342344
}
343345

344-
*value = vm->cache_fetch.page_addr[(addr >> 2) & MASK(RV_PAGE_SHIFT - 2)];
346+
*value =
347+
vm->cache_fetch[index].page_addr[(addr >> 2) & MASK(RV_PAGE_SHIFT - 2)];
345348

346349
/* fill into the cache */
347350
uint32_t block_off = (addr & RV_PAGE_MASK) & ~IC_BLOCK_MASK;
348-
blk->base = (const uint8_t *) vm->cache_fetch.page_addr + block_off;
351+
blk->base = (const uint8_t *) vm->cache_fetch[index].page_addr + block_off;
349352
blk->tag = tag;
350353
blk->valid = true;
351354
}

riscv.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ struct __hart_internal {
134134
*/
135135
uint32_t exc_cause, exc_val;
136136

137-
mmu_fetch_cache_t cache_fetch;
137+
mmu_fetch_cache_t cache_fetch[2];
138138
/* 2-entry direct-mapped with hash-based indexing */
139139
mmu_addr_cache_t cache_load[2];
140140
mmu_addr_cache_t cache_store;

0 commit comments

Comments
 (0)