Skip to content

Commit 0361252

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 7b0c3f3 commit 0361252

File tree

2 files changed

+11
-7
lines changed

2 files changed

+11
-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
/* Invalidate all 8 sets × 2 ways for load cache */
195196
for (int set = 0; set < 8; set++) {
196197
for (int way = 0; way < 2; way++)
@@ -388,7 +389,8 @@ static void mmu_fetch(hart_t *vm, uint32_t addr, uint32_t *value)
388389

389390
/* cache miss, Continue using the original va->pa*/
390391
uint32_t vpn = addr >> RV_PAGE_SHIFT;
391-
if (unlikely(vpn != vm->cache_fetch.n_pages)) {
392+
uint32_t index = __builtin_parity(vpn) & 0x1;
393+
if (unlikely(vpn != vm->cache_fetch[index].n_pages)) {
392394
mmu_translate(vm, &addr, (1 << 3), (1 << 6), false, RV_EXC_FETCH_FAULT,
393395
RV_EXC_FETCH_PFAULT);
394396
if (vm->error)
@@ -397,15 +399,16 @@ static void mmu_fetch(hart_t *vm, uint32_t addr, uint32_t *value)
397399
vm->mem_fetch(vm, addr >> RV_PAGE_SHIFT, &page_addr);
398400
if (vm->error)
399401
return;
400-
vm->cache_fetch.n_pages = vpn;
401-
vm->cache_fetch.page_addr = page_addr;
402+
vm->cache_fetch[index].n_pages = vpn;
403+
vm->cache_fetch[index].page_addr = page_addr;
402404
}
403405

404-
*value = vm->cache_fetch.page_addr[(addr >> 2) & MASK(RV_PAGE_SHIFT - 2)];
406+
*value =
407+
vm->cache_fetch[index].page_addr[(addr >> 2) & MASK(RV_PAGE_SHIFT - 2)];
405408

406409
/* fill into the cache */
407410
uint32_t block_off = (addr & RV_PAGE_MASK) & ~IC_BLOCK_MASK;
408-
blk->base = (const uint8_t *) vm->cache_fetch.page_addr + block_off;
411+
blk->base = (const uint8_t *) vm->cache_fetch[index].page_addr + block_off;
409412
blk->tag = tag;
410413
blk->valid = true;
411414
}

riscv.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,8 @@ struct __hart_internal {
140140
*/
141141
uint32_t exc_cause, exc_val;
142142

143-
mmu_fetch_cache_t cache_fetch;
143+
/* 2-entry direct-mapped with hash-based indexing */
144+
mmu_fetch_cache_t cache_fetch[2];
144145
/* 8-set × 2-way set-associative cache with 3-bit parity hash indexing */
145146
mmu_cache_set_t cache_load[8];
146147
/* 8-set × 2-way set-associative cache for store operations */

0 commit comments

Comments
 (0)