mirror of
https://github.com/ARMSX2/ARMSX3.git
synced 2026-08-24 16:58:52 -07:00
SPU: move the per-block recompiler diagnostics to trace
A 15 minute Prototype session wrote 56,881 log lines, and 49,644 of them came from
the SPU recompiler -- peaking at 2,473 lines in a single second, written to
/sdcard. The bursts land exactly when a game is already stalling to compile new
blocks, which is the worst possible moment to add synchronous file writes, and
they stop when compilation finishes. That matches the reported symptom: seconds of
lockup that recover on their own.
Every one of these is per-block or per-instruction:
8963 New SPU block compiled successfully was success
7833 Precompiling fallthrough was notice
4337 Precompiling filler space was notice
3449 SPU block is a loop was notice
2418 MFC_EAH / MFC_Cmd not constant was warning, per INSTRUCTION
1516 Trampoline simplified was error, and is routine
843 SPU Block Dump was notice, and is multi-line
696 GETLLAR pattern entry point was notice
~1400 PUTLLC16 / pattern breakage family was notice and success
Upstream can afford these: a desktop has a fast disk and nobody is writing to
external storage. Demoted to trace, so they stay available by raising the SPU
channel and cost nothing during normal play.
The genuine faults keep their level -- MFC_Cmd invalid size and unknown command
are still errors, and they are rare.
This does not claim compilation is free. It removes the logging so what remains
can be measured, which is not possible while the instrument is this loud.
This commit is contained in:
@@ -1466,7 +1466,7 @@ void spu_cache::initialize(bool build_existing_cache)
|
||||
{
|
||||
if (ls[start_new / 4] && g_spu_itype.decode(ls[start_new / 4]) != spu_itype::UNK)
|
||||
{
|
||||
spu_log.notice("Precompiling fallthrough to 0x%05x", start_new);
|
||||
spu_log.trace("Precompiling fallthrough to 0x%05x", start_new);
|
||||
func2 = compiler->analyse(ls.data(), start_new, &targets);
|
||||
block_addr = start_new;
|
||||
continue;
|
||||
@@ -1530,7 +1530,7 @@ void spu_cache::initialize(bool build_existing_cache)
|
||||
}
|
||||
|
||||
|
||||
spu_log.notice("Precompiling filler space at 0x%05x (next=0x%05x)", new_entry, next_func);
|
||||
spu_log.trace("Precompiling filler space at 0x%05x (next=0x%05x)", new_entry, next_func);
|
||||
func2 = compiler->analyse(ls.data(), new_entry, &targets);
|
||||
block_addr = new_entry;
|
||||
}
|
||||
@@ -2139,7 +2139,12 @@ spu_function_t spu_runtime::rebuild_ubertrampoline(u32 id_inst)
|
||||
if (w.level >= w.beg->first.size() || w.level >= it->first.size())
|
||||
{
|
||||
// If functions cannot be compared, assume smallest function
|
||||
spu_log.error("Trampoline simplified at ??? (level=%u)", w.level);
|
||||
// Routine control-flow simplification, not a failure -- it was at error level
|
||||
// and fired ~1500 times in a 15 minute session. Every diagnostic in this
|
||||
// recompiler is per-block or per-instruction, which upstream can afford and a
|
||||
// phone writing to /sdcard cannot: the burst lands exactly while a game is
|
||||
// already stalling to compile. Still reachable by raising the SPU channel.
|
||||
spu_log.trace("Trampoline simplified at ??? (level=%u)", w.level);
|
||||
#if defined(ARCH_X64)
|
||||
make_jump(0xe9, w.beg->second); // jmp rel32
|
||||
#elif defined(ARCH_ARM64)
|
||||
@@ -2178,7 +2183,7 @@ spu_function_t spu_runtime::rebuild_ubertrampoline(u32 id_inst)
|
||||
|
||||
if (it == m_flat_list.end())
|
||||
{
|
||||
spu_log.error("Trampoline simplified (II) at ??? (level=%u)", w.level);
|
||||
spu_log.trace("Trampoline simplified (II) at ??? (level=%u)", w.level);
|
||||
#if defined(ARCH_X64)
|
||||
make_jump(0xe9, w.beg->second); // jmp rel32
|
||||
#elif defined(ARCH_ARM64)
|
||||
@@ -6069,7 +6074,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
||||
getllar_starts[previous.lsa_pc] = true;
|
||||
g_fxo->get<putllc16_statistics_t>().breaking_reason[cause]++;
|
||||
|
||||
if (!spu_log.notice)
|
||||
if (!spu_log.trace)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -6109,7 +6114,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
||||
}
|
||||
|
||||
fmt::append(tracing, " of %d failures", fail_count);
|
||||
spu_log.notice("%s\n%s", break_error, tracing);
|
||||
spu_log.trace("%s\n%s", break_error, tracing);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -6126,7 +6131,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
||||
|
||||
g_fxo->get<rchcnt_statistics_t>().breaking_reason[cause]++;
|
||||
|
||||
if (!spu_log.notice)
|
||||
if (!spu_log.trace)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -6166,7 +6171,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
||||
}
|
||||
|
||||
fmt::append(tracing, " of %d failures", fail_count);
|
||||
spu_log.notice("%s\n%s", break_error, tracing);
|
||||
spu_log.trace("%s\n%s", break_error, tracing);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -6176,7 +6181,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
||||
{
|
||||
g_fxo->get<reduced_statistics_t>().breaking_reason[cause]++;
|
||||
|
||||
if (!spu_log.notice)
|
||||
if (!spu_log.trace)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -6221,12 +6226,12 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
||||
}
|
||||
|
||||
fmt::append(tracing, " of %d failures", fail_count);
|
||||
spu_log.notice("%s\n%s", break_error, tracing);
|
||||
spu_log.trace("%s\n%s", break_error, tracing);
|
||||
|
||||
std::string block_dump;
|
||||
this->dump(result, block_dump, previous.loop_pc, previous.loop_end + 1);
|
||||
|
||||
spu_log.notice("SPU Block Dump:\n%s", block_dump);
|
||||
spu_log.trace("SPU Block Dump:\n%s", block_dump);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -6437,7 +6442,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
||||
{
|
||||
if (!std::exchange(logged_block[target_pc / 4], true))
|
||||
{
|
||||
spu_log.notice("SPU block is a loop at [0x%05x -> 0x%05x]", state_it->pc, target_pc);
|
||||
spu_log.trace("SPU block is a loop at [0x%05x -> 0x%05x]", state_it->pc, target_pc);
|
||||
}
|
||||
|
||||
state_it->parent_target_index++;
|
||||
@@ -7959,7 +7964,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
||||
if (getllar_starts.emplace(atomic16->lsa_pc, false).second)
|
||||
{
|
||||
g_fxo->get<putllc16_statistics_t>().all++;
|
||||
spu_log.notice("[0x%05x] GETLLAR pattern entry point", pos);
|
||||
spu_log.trace("[0x%05x] GETLLAR pattern entry point", pos);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9287,7 +9292,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
||||
add_pattern(inst_attr::putllc16, pattern.put_pc - result.entry_point, value.data);
|
||||
}
|
||||
|
||||
spu_log.success("PUTLLC16 Pattern Detected! (mem_count=%d, put_pc=0x%x, pc_rel=%d, offset=0x%x, const=%u, two_regs=%d, reg=%u, runtime=%d, 0x%x-%s, pattern-hash=%s) (putllc0=%d, putllc16+0=%d, all=%d)"
|
||||
spu_log.trace("PUTLLC16 Pattern Detected! (mem_count=%d, put_pc=0x%x, pc_rel=%d, offset=0x%x, const=%u, two_regs=%d, reg=%u, runtime=%d, 0x%x-%s, pattern-hash=%s) (putllc0=%d, putllc16+0=%d, all=%d)"
|
||||
, pattern.mem_count, pattern.put_pc, value.type == v_relative, value.off18, value.type == v_const, value.type == v_reg2, value.reg, value.runtime16_select, entry_point, func_hash, pattern_hash, +stats.nowrite, ++stats.single, +stats.all);
|
||||
}
|
||||
|
||||
@@ -9393,7 +9398,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
||||
|
||||
if (likely_putllc_loop && !had_putllc_evaluation)
|
||||
{
|
||||
spu_log.notice("Likely missed PUTLLC16 patterns. (entry=0x%x)", entry_point);
|
||||
spu_log.trace("Likely missed PUTLLC16 patterns. (entry=0x%x)", entry_point);
|
||||
}
|
||||
|
||||
if (result.data.empty())
|
||||
|
||||
@@ -4155,7 +4155,7 @@ public:
|
||||
cache.add(func);
|
||||
}
|
||||
|
||||
spu_log.success("New SPU block compiled successfully (size=%u)", func_size);
|
||||
spu_log.trace("New SPU block compiled successfully (size=%u)", func_size);
|
||||
}
|
||||
|
||||
return fn;
|
||||
@@ -5292,7 +5292,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
spu_log.warning("[0x%x] MFC_EAH: $%u is not a zero constant", m_pos, +op.rt);
|
||||
spu_log.trace("[0x%x] MFC_EAH: $%u is not a zero constant", m_pos, +op.rt);
|
||||
//m_ir->CreateStore(val.value, spu_ptr(&spu_thread::ch_mfc_cmd, &spu_mfc_cmd::eah));
|
||||
return;
|
||||
}
|
||||
@@ -5650,7 +5650,7 @@ public:
|
||||
}
|
||||
|
||||
// Fallback to unoptimized WRCH implementation (TODO)
|
||||
spu_log.warning("[0x%x] MFC_Cmd: $%u is not a constant", m_pos, +op.rt);
|
||||
spu_log.trace("[0x%x] MFC_Cmd: $%u is not a constant", m_pos, +op.rt);
|
||||
break;
|
||||
}
|
||||
case MFC_WrListStallAck:
|
||||
|
||||
Reference in New Issue
Block a user