mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-31 20:41:45 +01:00
spu: Speed hacks - Do not starve PPU threads
optionally hint to the OS scheduler to give less attention to SPUs ui: Add speed 'hacks' as configurable options
This commit is contained in:
parent
4b5a30f53d
commit
df7b466656
@ -1750,6 +1750,7 @@ void named_thread::start_thread(const std::shared_ptr<void>& _this)
|
||||
try
|
||||
{
|
||||
LOG_TRACE(GENERAL, "Thread started");
|
||||
on_spawn();
|
||||
on_task();
|
||||
LOG_TRACE(GENERAL, "Thread ended");
|
||||
}
|
||||
|
@ -258,6 +258,9 @@ protected:
|
||||
// Thread finalization (called after on_task)
|
||||
virtual void on_exit() {}
|
||||
|
||||
// Called once upon thread spawn within the thread's own context
|
||||
virtual void on_spawn() {}
|
||||
|
||||
public:
|
||||
// ID initialization
|
||||
virtual void on_init(const std::shared_ptr<void>& _this)
|
||||
|
@ -4,6 +4,11 @@
|
||||
#include "CPUThread.h"
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Utilities/GDBDebugServer.h"
|
||||
#include "Utilities/Config.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
DECLARE(cpu_thread::g_threads_created){0};
|
||||
DECLARE(cpu_thread::g_threads_deleted){0};
|
||||
@ -178,3 +183,34 @@ std::string cpu_thread::dump() const
|
||||
{
|
||||
return fmt::format("Type: %s\n" "State: %s\n", typeid(*this).name(), state.load());
|
||||
}
|
||||
|
||||
void cpu_thread::set_native_priority(int priority)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
HANDLE _this_thread = GetCurrentThread();
|
||||
INT native_priority = THREAD_PRIORITY_NORMAL;
|
||||
|
||||
switch (priority)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
native_priority = THREAD_PRIORITY_ABOVE_NORMAL;
|
||||
break;
|
||||
case -1:
|
||||
native_priority = THREAD_PRIORITY_BELOW_NORMAL;
|
||||
break;
|
||||
}
|
||||
|
||||
SetThreadPriority(_this_thread, native_priority);
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
void cpu_thread::set_ideal_processor_core(int core)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
HANDLE _this_thread = GetCurrentThread();
|
||||
SetThreadIdealProcessor(_this_thread, core);
|
||||
#endif
|
||||
}
|
@ -65,6 +65,10 @@ public:
|
||||
|
||||
// Callback for cpu_flag::suspend
|
||||
virtual void cpu_sleep() {}
|
||||
|
||||
//native scheduler tweaks
|
||||
void set_native_priority(int priority);
|
||||
void set_ideal_processor_core(int core);
|
||||
};
|
||||
|
||||
inline cpu_thread* get_current_cpu_thread() noexcept
|
||||
|
@ -20,6 +20,8 @@
|
||||
|
||||
#include <cmath>
|
||||
#include <cfenv>
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
bool operator ==(const u128& lhs, const u128& rhs)
|
||||
@ -49,10 +51,14 @@ cfg::map_entry<spu_decoder_type> g_cfg_spu_decoder(cfg::root.core, "SPU Decoder"
|
||||
});
|
||||
|
||||
cfg::bool_entry g_cfg_spu_debug(cfg::root.core, "SPU Debug");
|
||||
cfg::bool_entry g_cfg_core_bind_spu_cores(cfg::root.core, "Bind SPU threads to secondary cores");
|
||||
cfg::bool_entry g_cfg_core_lower_spu_priority(cfg::root.core, "Lower SPU thread priority");
|
||||
|
||||
const spu_decoder<spu_interpreter_precise> s_spu_interpreter_precise;
|
||||
const spu_decoder<spu_interpreter_fast> s_spu_interpreter_fast;
|
||||
|
||||
std::atomic<u64> g_num_spu_threads = { 0ull };
|
||||
|
||||
void spu_int_ctrl_t::set(u64 ints)
|
||||
{
|
||||
// leave only enabled interrupts
|
||||
@ -134,6 +140,29 @@ spu_imm_table_t::spu_imm_table_t()
|
||||
}
|
||||
}
|
||||
|
||||
void SPUThread::on_spawn()
|
||||
{
|
||||
if (g_cfg_core_bind_spu_cores)
|
||||
{
|
||||
//Get next secondary core number
|
||||
auto core_count = std::thread::hardware_concurrency();
|
||||
if (core_count > 0 && core_count <= 16)
|
||||
{
|
||||
auto half_count = core_count / 2;
|
||||
auto assigned_secondary_core = ((g_num_spu_threads % half_count) * 2) + 1;
|
||||
|
||||
set_ideal_processor_core(assigned_secondary_core);
|
||||
}
|
||||
}
|
||||
|
||||
if (g_cfg_core_lower_spu_priority)
|
||||
{
|
||||
set_native_priority(-1);
|
||||
}
|
||||
|
||||
g_num_spu_threads++;
|
||||
}
|
||||
|
||||
void SPUThread::on_init(const std::shared_ptr<void>& _this)
|
||||
{
|
||||
if (!offset)
|
||||
@ -208,7 +237,7 @@ extern thread_local std::string(*g_tls_log_prefix)();
|
||||
void SPUThread::cpu_task()
|
||||
{
|
||||
std::fesetround(FE_TOWARDZERO);
|
||||
|
||||
|
||||
if (g_cfg_spu_decoder.get() == spu_decoder_type::asmjit)
|
||||
{
|
||||
if (!spu_db) spu_db = fxm::get_always<SPUDatabase>();
|
||||
|
@ -504,6 +504,7 @@ public:
|
||||
class SPUThread : public cpu_thread
|
||||
{
|
||||
public:
|
||||
virtual void on_spawn() override;
|
||||
virtual void on_init(const std::shared_ptr<void>&) override;
|
||||
virtual std::string get_name() const override;
|
||||
virtual std::string dump() const override;
|
||||
|
@ -226,7 +226,7 @@ SettingsDialog::SettingsDialog(wxWindow* parent, const std::string& path)
|
||||
|
||||
std::vector<std::unique_ptr<cfg_adapter>> pads;
|
||||
|
||||
static const u32 width = 458;
|
||||
static const u32 width = 512;
|
||||
static const u32 height = 400;
|
||||
|
||||
// Settings panels
|
||||
@ -310,6 +310,8 @@ SettingsDialog::SettingsDialog(wxWindow* parent, const std::string& path)
|
||||
wxComboBox* cbox_sys_lang = new wxComboBox(p_system, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY);
|
||||
|
||||
wxCheckBox* chbox_core_hook_stfunc = new wxCheckBox(p_core, wxID_ANY, "Hook static functions");
|
||||
wxCheckBox* chbox_core_bind_spu_threads = new wxCheckBox(p_core, wxID_ANY, "Bind SPU threads to secondary cores");
|
||||
wxCheckBox* chbox_core_lower_spu_priority = new wxCheckBox(p_core, wxID_ANY, "Lower SPU thread priority");
|
||||
wxCheckBox* chbox_vfs_enable_host_root = new wxCheckBox(p_system, wxID_ANY, "Enable /host_root/");
|
||||
wxCheckBox* chbox_gs_log_prog = new wxCheckBox(p_graphics, wxID_ANY, "Log Shader Programs");
|
||||
wxCheckBox* chbox_gs_dump_depth = new wxCheckBox(p_graphics, wxID_ANY, "Write Depth Buffer");
|
||||
@ -391,6 +393,8 @@ SettingsDialog::SettingsDialog(wxWindow* parent, const std::string& path)
|
||||
EnableModuleList(rbox_lib_loader->GetSelection());
|
||||
|
||||
pads.emplace_back(std::make_unique<checkbox_pad>(cfg_location{ "Core", "Hook static functions" }, chbox_core_hook_stfunc));
|
||||
pads.emplace_back(std::make_unique<checkbox_pad>(cfg_location{ "Core", "Bind SPU threads to secondary cores" }, chbox_core_bind_spu_threads));
|
||||
pads.emplace_back(std::make_unique<checkbox_pad>(cfg_location{ "Core", "Lower SPU thread priority" }, chbox_core_lower_spu_priority));
|
||||
pads.emplace_back(std::make_unique<checkbox_pad>(cfg_location{ "VFS", "Enable /host_root/" }, chbox_vfs_enable_host_root));
|
||||
|
||||
pads.emplace_back(std::make_unique<combobox_pad>(cfg_location{ "Video", "Renderer" }, cbox_gs_render));
|
||||
@ -482,6 +486,8 @@ SettingsDialog::SettingsDialog(wxWindow* parent, const std::string& path)
|
||||
s_subpanel_core1->Add(rbox_ppu_decoder, wxSizerFlags().Border(wxALL, 5).Expand());
|
||||
s_subpanel_core1->Add(rbox_spu_decoder, wxSizerFlags().Border(wxALL, 5).Expand());
|
||||
s_subpanel_core1->Add(chbox_core_hook_stfunc, wxSizerFlags().Border(wxALL, 5).Expand());
|
||||
s_subpanel_core1->Add(chbox_core_bind_spu_threads, wxSizerFlags().Border(wxALL, 5).Expand());
|
||||
s_subpanel_core1->Add(chbox_core_lower_spu_priority, wxSizerFlags().Border(wxALL, 5).Expand());
|
||||
s_subpanel_core2->Add(rbox_lib_loader, wxSizerFlags().Border(wxALL, 5).Expand());
|
||||
s_subpanel_core2->Add(s_round_core_lle, wxSizerFlags().Border(wxALL, 5).Expand());
|
||||
s_subpanel_core->Add(s_subpanel_core1);
|
||||
|
Loading…
x
Reference in New Issue
Block a user