SPU Debugger: Measure rate of block ran

This commit is contained in:
Elad 2026-03-11 16:11:45 +02:00
parent 619fe7b14e
commit e83034624b
10 changed files with 73 additions and 23 deletions

View File

@ -1322,8 +1322,9 @@ extern std::shared_ptr<CPUDisAsm> make_disasm(const cpu_thread* cpu, shared_ptr<
void cpu_thread::dump_all(std::string& ret) const
{
std::any func_data;
std::any misc_data;
ret += dump_misc();
dump_misc(ret, misc_data);
ret += '\n';
dump_regs(ret, func_data);
ret += '\n';
@ -1371,9 +1372,9 @@ std::vector<std::pair<u32, u32>> cpu_thread::dump_callstack_list() const
return {};
}
std::string cpu_thread::dump_misc() const
void cpu_thread::dump_misc(std::string& ret, std::any& /*custom_data*/) const
{
return fmt::format("%s[0x%x]; State: %s\n", get_class() == thread_class::ppu ? "PPU" : get_class() == thread_class::spu ? "SPU" : "RSX", id, state.load());
fmt::append(ret, "%s[0x%x]; State: %s\n", get_class() == thread_class::ppu ? "PPU" : get_class() == thread_class::spu ? "SPU" : "RSX", id, state.load());
}
bool cpu_thread::suspend_work::push(cpu_thread* _this) noexcept

View File

@ -176,7 +176,7 @@ public:
virtual std::vector<std::pair<u32, u32>> dump_callstack_list() const;
// Get CPU dump of misc information
virtual std::string dump_misc() const;
virtual void dump_misc(std::string& ret, std::any& /*custom_data*/) const;
// Thread entry point function
virtual void cpu_task() = 0;

View File

@ -1364,9 +1364,7 @@ void ppu_thread::dump_regs(std::string& ret, std::any& custom_data) const
u32 preferred_cr_field_index = 7;
};
dump_registers_data_t* func_data = nullptr;
func_data = std::any_cast<dump_registers_data_t>(&custom_data);
dump_registers_data_t* func_data = std::any_cast<dump_registers_data_t>(&custom_data);
if (!func_data)
{
@ -2039,9 +2037,9 @@ std::vector<std::pair<u32, u32>> ppu_thread::dump_callstack_list() const
return call_stack_list;
}
std::string ppu_thread::dump_misc() const
void ppu_thread::dump_misc(std::string& ret, std::any& custom_data) const
{
std::string ret = cpu_thread::dump_misc();
cpu_thread::dump_misc(ret, custom_data);
if (ack_suspend)
{
@ -2096,7 +2094,6 @@ std::string ppu_thread::dump_misc() const
{
ret += '\n';
}
return ret;
}
void ppu_thread::dump_all(std::string& ret) const

View File

@ -145,7 +145,7 @@ public:
virtual void dump_regs(std::string&, std::any& custom_data) const override;
virtual std::string dump_callstack() const override;
virtual std::vector<std::pair<u32, u32>> dump_callstack_list() const override;
virtual std::string dump_misc() const override;
virtual void dump_misc(std::string& ret, std::any& custom_data) const override;
virtual void dump_all(std::string&) const override;
virtual void cpu_task() override final;
virtual void cpu_sleep() override;

View File

@ -1139,11 +1139,62 @@ std::vector<std::pair<u32, u32>> spu_thread::dump_callstack_list() const
return call_stack_list;
}
std::string spu_thread::dump_misc() const
void spu_thread::dump_misc(std::string& ret, std::any& custom_data) const
{
std::string ret = cpu_thread::dump_misc();
cpu_thread::dump_misc(ret, custom_data);
fmt::append(ret, "Block Weight: %u (Retreats: %u)", block_counter, block_failure);
struct dump_misc_data_t
{
u32 cpu_id = umax;
u64 last_read_time = umax;
u64 last_block_counter = umax;
u64 update_count = 0;
std::pair<u64, u64> update(u64 current_block_counter, u64 current_timestamp = get_system_time())
{
const u64 diff_time = current_timestamp <= last_read_time ? 0 : current_timestamp - last_read_time;
const u64 diff_block = current_block_counter <= last_block_counter ? 0 : current_block_counter - last_block_counter;
if (last_read_time == umax || update_count >= 1000)
{
last_read_time = current_timestamp;
last_block_counter = current_block_counter;
update_count = 0;
}
else if (diff_time >= 100000 && diff_block >= 100)
{
// Update values to measure rate (but not fully so rate can be measured later)
last_read_time += diff_time / 10 * 9;
last_block_counter += diff_block / 10 * 9;
update_count++;
}
return {diff_time, diff_block};
}
};
dump_misc_data_t* func_data = std::any_cast<dump_misc_data_t>(&custom_data);
if (!func_data)
{
custom_data.reset();
custom_data = std::make_any<dump_misc_data_t>();
func_data = ensure(std::any_cast<dump_misc_data_t>(&custom_data));
}
if (func_data->cpu_id != this->id)
{
*func_data = {};
func_data->cpu_id = this->id;
}
const u64 current_block_counter = atomic_storage<u64>::load(block_counter);
const auto [diff_time, diff_block] = func_data->update(current_block_counter);
const u64 rate_of_diff = diff_block ? std::max<u64>(1, utils::rational_mul<u64>(diff_block, 1'000'000, std::max<u64>(diff_time, 1))) : 0;
fmt::append(ret, "Block Weight: log10(%u/second): %.1f (Retreats: %u)", rate_of_diff, std::log10(std::max<u64>(rate_of_diff, 10)), block_failure);
if (u64 hash = atomic_storage<u64>::load(block_hash))
{
@ -1194,8 +1245,6 @@ std::string spu_thread::dump_misc() const
break;
}
}
return ret;
}
void spu_thread::cpu_on_stop()

View File

@ -630,7 +630,7 @@ public:
virtual void dump_regs(std::string&, std::any& custom_data) const override;
virtual std::string dump_callstack() const override;
virtual std::vector<std::pair<u32, u32>> dump_callstack_list() const override;
virtual std::string dump_misc() const override;
virtual void dump_misc(std::string& ret, std::any& custom_data) const override;
virtual void cpu_task() override final;
virtual void cpu_on_stop() override;
virtual void cpu_return() override;

View File

@ -2774,9 +2774,9 @@ namespace rsx
recovered_fifo_cmds_history.push({fifo_ctrl->last_cmd(), current_time});
}
std::string thread::dump_misc() const
void thread::dump_misc(std::string& ret, std::any& custom_data) const
{
std::string ret = cpu_thread::dump_misc();
cpu_thread::dump_misc(ret, custom_data);
const auto flags = +state;
@ -2789,8 +2789,6 @@ namespace rsx
{
fmt::append(ret, "\n");
}
return ret;
}
std::vector<std::pair<u32, u32>> thread::dump_callstack_list() const

View File

@ -122,7 +122,7 @@ namespace rsx
std::unique_ptr<FIFO::FIFO_control> fifo_ctrl;
atomic_t<bool> rsx_thread_running{ false };
std::vector<std::pair<u32, u32>> dump_callstack_list() const override;
std::string dump_misc() const override;
void dump_misc(std::string& ret, std::any& custom_data) const override;
protected:
FIFO::flattening_helper m_flattener;

View File

@ -1469,8 +1469,11 @@ void debugger_frame::WritePanels(cpu_thread* cpu)
int loc = m_misc_state->verticalScrollBar()->value();
int hloc = m_misc_state->horizontalScrollBar()->value();
m_last_misc_state.clear();
cpu->dump_misc(m_last_misc_state, m_dump_misc_func_data);
m_misc_state->clear();
m_misc_state->setPlainText(QString::fromStdString(cpu->dump_misc()));
m_misc_state->setPlainText(QString::fromStdString(m_last_misc_state));
m_misc_state->verticalScrollBar()->setValue(loc);
m_misc_state->horizontalScrollBar()->setValue(hloc);

View File

@ -69,7 +69,9 @@ class debugger_frame : public custom_dock_widget
u32 m_last_pc = -1;
std::vector<char> m_last_query_state;
std::string m_last_reg_state;
std::string m_last_misc_state;
std::any m_dump_reg_func_data;
std::any m_dump_misc_func_data;
std::vector<std::function<cpu_thread*()>> m_threads_info;
u32 m_last_step_over_breakpoint = -1;
u64 m_ui_update_ctr = 0;