debug wrap perf counters
This commit is contained in:
parent
1dd8e4f833
commit
dedd3c82dc
|
@ -22,28 +22,36 @@
|
||||||
struct UltraInstructionCache {
|
struct UltraInstructionCache {
|
||||||
u32 pc[ICACHE_SIZE];
|
u32 pc[ICACHE_SIZE];
|
||||||
u16 opcode[ICACHE_SIZE];
|
u16 opcode[ICACHE_SIZE];
|
||||||
|
#ifdef DEBUG
|
||||||
u64 hits;
|
u64 hits;
|
||||||
u64 misses;
|
u64 misses;
|
||||||
|
#endif
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
for (int i = 0; i < ICACHE_SIZE; i++) {
|
for (int i = 0; i < ICACHE_SIZE; i++) {
|
||||||
pc[i] = 0xFFFFFFFF;
|
pc[i] = 0xFFFFFFFF;
|
||||||
opcode[i] = 0;
|
opcode[i] = 0;
|
||||||
}
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
hits = 0;
|
hits = 0;
|
||||||
misses = 0;
|
misses = 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 fetch(u32 addr) {
|
u16 fetch(u32 addr) {
|
||||||
u32 index = (addr >> 1) & ICACHE_MASK;
|
u32 index = (addr >> 1) & ICACHE_MASK;
|
||||||
|
|
||||||
if (pc[index] == addr) {
|
if (pc[index] == addr) {
|
||||||
|
#ifdef DEBUG
|
||||||
hits++;
|
hits++;
|
||||||
|
#endif
|
||||||
return opcode[index];
|
return opcode[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache miss - fetch from memory
|
// Cache miss - fetch from memory
|
||||||
|
#ifdef DEBUG
|
||||||
misses++;
|
misses++;
|
||||||
|
#endif
|
||||||
u16 op = IReadMem16(addr);
|
u16 op = IReadMem16(addr);
|
||||||
pc[index] = addr;
|
pc[index] = addr;
|
||||||
opcode[index] = op;
|
opcode[index] = op;
|
||||||
|
@ -55,24 +63,30 @@ static UltraInstructionCache g_icache;
|
||||||
|
|
||||||
// === PERFORMANCE STATS ===
|
// === PERFORMANCE STATS ===
|
||||||
struct UltraStats {
|
struct UltraStats {
|
||||||
|
#ifdef DEBUG
|
||||||
u64 instructions;
|
u64 instructions;
|
||||||
u64 cycles;
|
u64 cycles;
|
||||||
u32 mmu_state_changes;
|
u32 mmu_state_changes;
|
||||||
|
#endif
|
||||||
bool mmu_enabled;
|
bool mmu_enabled;
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
|
#ifdef DEBUG
|
||||||
instructions = 0;
|
instructions = 0;
|
||||||
cycles = 0;
|
cycles = 0;
|
||||||
mmu_state_changes = 0;
|
mmu_state_changes = 0;
|
||||||
|
#endif
|
||||||
mmu_enabled = ::mmu_enabled();
|
mmu_enabled = ::mmu_enabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_mmu() {
|
void check_mmu() {
|
||||||
bool current_mmu = ::mmu_enabled();
|
bool current_mmu = ::mmu_enabled();
|
||||||
if (current_mmu != mmu_enabled) {
|
if (current_mmu != mmu_enabled) {
|
||||||
|
#ifdef DEBUG
|
||||||
mmu_state_changes++;
|
mmu_state_changes++;
|
||||||
mmu_enabled = current_mmu;
|
|
||||||
INFO_LOG(INTERPRETER, "🔄 MMU state changed: %s", current_mmu ? "ENABLED" : "DISABLED");
|
INFO_LOG(INTERPRETER, "🔄 MMU state changed: %s", current_mmu ? "ENABLED" : "DISABLED");
|
||||||
|
#endif
|
||||||
|
mmu_enabled = current_mmu;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -117,18 +131,27 @@ static void ultra_interpreter_run() {
|
||||||
OpPtr[op](op);
|
OpPtr[op](op);
|
||||||
sh4cycles.executeCycles(op);
|
sh4cycles.executeCycles(op);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
// Update performance counters
|
// Update performance counters
|
||||||
g_stats.instructions++;
|
g_stats.instructions++;
|
||||||
g_stats.cycles += OpDesc[op]->IssueCycles;
|
g_stats.cycles += OpDesc[op]->IssueCycles;
|
||||||
|
#endif
|
||||||
|
|
||||||
// ARM64 prefetch optimization
|
// ARM64 prefetch optimization
|
||||||
#ifdef __aarch64__
|
#ifdef __aarch64__
|
||||||
|
#ifdef DEBUG
|
||||||
if (__builtin_expect((g_stats.instructions & 0x7) == 0, 0)) {
|
if (__builtin_expect((g_stats.instructions & 0x7) == 0, 0)) {
|
||||||
|
#else
|
||||||
|
// Use a simple counter for prefetching in release builds
|
||||||
|
static u32 prefetch_counter = 0;
|
||||||
|
if (__builtin_expect((++prefetch_counter & 0x7) == 0, 0)) {
|
||||||
|
#endif
|
||||||
// Prefetch next cache line every 8 instructions
|
// Prefetch next cache line every 8 instructions
|
||||||
__builtin_prefetch(reinterpret_cast<void*>(static_cast<uintptr_t>(next_pc + 32)), 0, 1);
|
__builtin_prefetch(reinterpret_cast<void*>(static_cast<uintptr_t>(next_pc + 32)), 0, 1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
// Check MMU state periodically
|
// Check MMU state periodically
|
||||||
if (__builtin_expect((g_stats.instructions & 0xFF) == 0, 0)) {
|
if (__builtin_expect((g_stats.instructions & 0xFF) == 0, 0)) {
|
||||||
g_stats.check_mmu();
|
g_stats.check_mmu();
|
||||||
|
@ -142,6 +165,13 @@ static void ultra_interpreter_run() {
|
||||||
INFO_LOG(INTERPRETER, "📊 ULTRA-INTERPRETER: %llu instructions, %.1f%% icache hit ratio, %s MMU",
|
INFO_LOG(INTERPRETER, "📊 ULTRA-INTERPRETER: %llu instructions, %.1f%% icache hit ratio, %s MMU",
|
||||||
g_stats.instructions, cache_hit_ratio, g_stats.mmu_enabled ? "POST" : "PRE");
|
g_stats.instructions, cache_hit_ratio, g_stats.mmu_enabled ? "POST" : "PRE");
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
// Check MMU state periodically in release builds (without logging)
|
||||||
|
static u32 mmu_check_counter = 0;
|
||||||
|
if (__builtin_expect((++mmu_check_counter & 0xFF) == 0, 0)) {
|
||||||
|
g_stats.check_mmu();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
} while (p_sh4rcb->cntx.cycle_counter > 0);
|
} while (p_sh4rcb->cntx.cycle_counter > 0);
|
||||||
|
|
||||||
|
@ -157,6 +187,7 @@ static void ultra_interpreter_run() {
|
||||||
}
|
}
|
||||||
|
|
||||||
INFO_LOG(INTERPRETER, "🏁 ULTRA-INTERPRETER: Finished execution");
|
INFO_LOG(INTERPRETER, "🏁 ULTRA-INTERPRETER: Finished execution");
|
||||||
|
#ifdef DEBUG
|
||||||
INFO_LOG(INTERPRETER, "📊 Final stats: %llu instructions, %llu cycles, %d MMU changes",
|
INFO_LOG(INTERPRETER, "📊 Final stats: %llu instructions, %llu cycles, %d MMU changes",
|
||||||
g_stats.instructions, g_stats.cycles, g_stats.mmu_state_changes);
|
g_stats.instructions, g_stats.cycles, g_stats.mmu_state_changes);
|
||||||
|
|
||||||
|
@ -164,6 +195,7 @@ static void ultra_interpreter_run() {
|
||||||
(float)g_icache.hits / (g_icache.hits + g_icache.misses) * 100.0f : 0.0f;
|
(float)g_icache.hits / (g_icache.hits + g_icache.misses) * 100.0f : 0.0f;
|
||||||
INFO_LOG(INTERPRETER, "📊 Instruction cache: %llu hits, %llu misses, %.1f%% hit ratio",
|
INFO_LOG(INTERPRETER, "📊 Instruction cache: %llu hits, %llu misses, %.1f%% hit ratio",
|
||||||
g_icache.hits, g_icache.misses, cache_hit_ratio);
|
g_icache.hits, g_icache.misses, cache_hit_ratio);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// === ULTRA-INTERPRETER INTERFACE ===
|
// === ULTRA-INTERPRETER INTERFACE ===
|
||||||
|
|
Loading…
Reference in New Issue