1
0
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:
kd-11 2017-04-23 23:09:27 +03:00
parent 4b5a30f53d
commit df7b466656
7 changed files with 82 additions and 2 deletions

View File

@ -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");
}

View File

@ -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)

View File

@ -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
}

View File

@ -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

View File

@ -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>();

View File

@ -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;

View File

@ -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);