From 2ed630c6f2fa4d10a1338d357809aa4ac0cd2717 Mon Sep 17 00:00:00 2001 From: Yen-Fu Chen Date: Sat, 18 Nov 2023 20:14:55 +0800 Subject: [PATCH] Add frequency profiler --- src/cache.c | 52 ++++++++++++++++++++++++++++++++++++++++++--- src/cache.h | 2 ++ src/compile.c | 3 ++- src/riscv.c | 8 +++---- src/riscv_private.h | 1 + 5 files changed, 58 insertions(+), 8 deletions(-) diff --git a/src/cache.c b/src/cache.c index 506a625a..debb23da 100644 --- a/src/cache.c +++ b/src/cache.c @@ -6,6 +6,8 @@ #include #include #include +#include +#include #include #include #ifndef MIR @@ -18,7 +20,7 @@ /* THRESHOLD is set to identify hot spots. Once the frequency of use for a block * exceeds the THRESHOLD, the JIT compiler flow is triggered. */ -#define THRESHOLD 32768 +#define THRESHOLD 4096 #if RV32_HAS(JIT) #ifndef MIR #define CODE_CACHE_SIZE (64 * 1024 * 1024) @@ -544,8 +546,10 @@ void *cache_put(cache_t *cache, uint32_t key, void *value) return delete_value; } +uint64_t freq[4097] = {0}; void cache_free(cache_t *cache, void (*callback)(void *)) { + uint64_t total_times = 0; #if RV32_HAS(ARC) for (int i = 0; i < N_CACHE_LIST_TYPES; i++) { arc_entry_t *entry, *safe; @@ -567,12 +571,54 @@ void cache_free(cache_t *cache, void (*callback)(void *)) lfu_entry_t) #endif #endif - callback(entry->value); + { + freq[entry->frequency]++; + total_times += entry->frequency; + } } - mpool_destroy(cache_mp); free(cache->map->ht_list_head); free(cache->map); free(cache); + for (int i = 0; i <= 4096; i++) { + if (freq[i]) { + printf("%4d | %10ld\n", i, freq[i]); + } + } +} + +uint32_t cache_freq(struct cache *cache, uint32_t key) +{ + if (!cache->capacity || + hlist_empty(&cache->map->ht_list_head[cache_hash(key)])) + return 0; +#if RV32_HAS(ARC) + arc_entry_t *entry = NULL; +#ifdef __HAVE_TYPEOF + hlist_for_each_entry (entry, &cache->map->ht_list_head[cache_hash(key)], + ht_list) +#else + hlist_for_each_entry (entry, &cache->map->ht_list_head[cache_hash(key)], + ht_list, arc_entry_t) +#endif + { + if (entry->key == key) + return entry->frequency; + } +#else + lfu_entry_t *entry = NULL; +#ifdef __HAVE_TYPEOF + hlist_for_each_entry (entry, &cache->map->ht_list_head[cache_hash(key)], + ht_list) +#else + hlist_for_each_entry (entry, &cache->map->ht_list_head[cache_hash(key)], + ht_list, lfu_entry_t) +#endif + { + if (entry->key == key) + return entry->frequency; + } +#endif + return 0; } #if RV32_HAS(JIT) diff --git a/src/cache.h b/src/cache.h index 537480d5..f80bf5fc 100644 --- a/src/cache.h +++ b/src/cache.h @@ -59,3 +59,5 @@ uint8_t *code_cache_add(struct cache *cache, uint64_t align); #endif #endif + +uint32_t cache_freq(struct cache *cache, uint32_t key); \ No newline at end of file diff --git a/src/compile.c b/src/compile.c index 667c69cb..39944ff8 100644 --- a/src/compile.c +++ b/src/compile.c @@ -451,12 +451,13 @@ static void gen_fuse7(riscv_t *rv UNUSED, rv_insn_t *ir, char *gencode) } #undef RVOP +uint64_t count = 0; static void trace_ebb(riscv_t *rv, char *gencode, rv_insn_t *ir, set_t *set) { while (1) { if (set_add(set, ir->pc)) dispatch_table[ir->opcode](rv, ir, gencode); - + count++; if (!ir->next) break; ir = ir->next; diff --git a/src/riscv.c b/src/riscv.c index de4876f9..2b1f2058 100644 --- a/src/riscv.c +++ b/src/riscv.c @@ -162,10 +162,10 @@ void rv_delete(riscv_t *rv) #if !RV32_HAS(JIT) block_map_destroy(rv); #else -// cache_free(rv->block_cache, NULL); -// #ifdef MIR -// cache_free(rv->code_cache, NULL); -// #endif + cache_free(rv->block_cache, NULL); +#ifdef MIR + cache_free(rv->code_cache, NULL); +#endif #endif free(rv); } diff --git a/src/riscv_private.h b/src/riscv_private.h index ae368db7..ee0c65a3 100644 --- a/src/riscv_private.h +++ b/src/riscv_private.h @@ -62,6 +62,7 @@ typedef struct block { struct block *predict; /**< block prediction */ rv_insn_t *ir_head, *ir_tail; /**< the first and last ir for this block */ + bool backward; #if RV32_HAS(JIT) bool hot; /**< Determine the block is hotspot or not */ #endif