mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 02:32:36 +01:00
Scheduler overhaul
This commit is contained in:
parent
a7acb84b8b
commit
9d895e6b15
@ -2709,9 +2709,18 @@ u64 thread_ctrl::get_affinity_mask(thread_class group)
|
||||
break;
|
||||
case 16:
|
||||
// 1700, 1800, 2700, TR 1900X family
|
||||
ppu_mask = 0b1111111100000000;
|
||||
spu_mask = ppu_mask;
|
||||
rsx_mask = 0b0000000000111100;
|
||||
if (g_cfg.core.thread_scheduler == thread_scheduler_mode::alt)
|
||||
{
|
||||
ppu_mask = 0b0010000010000000;
|
||||
spu_mask = 0b0000101010101010;
|
||||
rsx_mask = 0b1000000000000000;
|
||||
}
|
||||
else
|
||||
{
|
||||
ppu_mask = 0b1111111100000000;
|
||||
spu_mask = ppu_mask;
|
||||
rsx_mask = 0b0000000000111100;
|
||||
}
|
||||
break;
|
||||
case 12:
|
||||
// 1600, 2600 family, Assign threads 3-12
|
||||
@ -2739,16 +2748,36 @@ u64 thread_ctrl::get_affinity_mask(thread_class group)
|
||||
spu_mask = 0b000000111111000000000000;
|
||||
rsx_mask = 0b000000000000111111000000;
|
||||
break;
|
||||
default:
|
||||
if (thread_count >= 16)
|
||||
case 16:
|
||||
// 5800X
|
||||
if (g_cfg.core.thread_scheduler == thread_scheduler_mode::alt)
|
||||
{
|
||||
ppu_mask = 0b0000000011110000;
|
||||
spu_mask = 0b1111111100000000;
|
||||
rsx_mask = 0b0000000000001111;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Verified by more than one windows user on 16-thread CPU
|
||||
ppu_mask = spu_mask = rsx_mask = (0b10101010101010101010101010101010 & all_cores_mask);
|
||||
}
|
||||
case 12:
|
||||
// 5600X
|
||||
if (g_cfg.core.thread_scheduler == thread_scheduler_mode::alt)
|
||||
{
|
||||
ppu_mask = 0b000000001100;
|
||||
spu_mask = 0b111111110000;
|
||||
rsx_mask = 0b000000000011;
|
||||
}
|
||||
else
|
||||
{
|
||||
ppu_mask = spu_mask = rsx_mask = all_cores_mask;
|
||||
}
|
||||
default:
|
||||
if (thread_count > 24)
|
||||
{
|
||||
ppu_mask = spu_mask = rsx_mask = (0b10101010101010101010101010101010 & all_cores_mask);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -2774,23 +2803,8 @@ u64 thread_ctrl::get_affinity_mask(thread_class group)
|
||||
}
|
||||
case native_core_arrangement::intel_ht:
|
||||
{
|
||||
/* This has been disabled as it seems to degrade performance instead of improving it.
|
||||
if (thread_count <= 4)
|
||||
{
|
||||
//i3 or worse
|
||||
switch (group)
|
||||
{
|
||||
case thread_class::rsx:
|
||||
case thread_class::ppu:
|
||||
return (0b0101 & all_cores_mask);
|
||||
case thread_class::spu:
|
||||
return (0b1010 & all_cores_mask);
|
||||
case thread_class::general:
|
||||
return all_cores_mask;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if (thread_count >= 12 && g_cfg.core.thread_scheduler == thread_scheduler_mode::alt)
|
||||
return (0b10101010101010101010101010101010 & all_cores_mask); // Potentially improves performance by mimicking HT off
|
||||
return all_cores_mask;
|
||||
}
|
||||
}
|
||||
|
@ -405,7 +405,7 @@ void cpu_thread::operator()()
|
||||
{
|
||||
g_tls_this_thread = this;
|
||||
|
||||
if (g_cfg.core.thread_scheduler_enabled)
|
||||
if (g_cfg.core.thread_scheduler != thread_scheduler_mode::os)
|
||||
{
|
||||
thread_ctrl::set_thread_affinity_mask(thread_ctrl::get_affinity_mask(id_type() == 1 ? thread_class::ppu : thread_class::spu));
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ namespace rsx
|
||||
|
||||
m_thread_id = std::this_thread::get_id();
|
||||
|
||||
if (g_cfg.core.thread_scheduler_enabled)
|
||||
if (g_cfg.core.thread_scheduler != thread_scheduler_mode::os)
|
||||
{
|
||||
thread_ctrl::set_thread_affinity_mask(thread_ctrl::get_affinity_mask(thread_class::rsx));
|
||||
}
|
||||
|
@ -639,7 +639,7 @@ namespace rsx
|
||||
// Raise priority above other threads
|
||||
thread_ctrl::scoped_priority high_prio(+1);
|
||||
|
||||
if (g_cfg.core.thread_scheduler_enabled)
|
||||
if (g_cfg.core.thread_scheduler != thread_scheduler_mode::os)
|
||||
{
|
||||
thread_ctrl::set_thread_affinity_mask(thread_ctrl::get_affinity_mask(thread_class::rsx));
|
||||
}
|
||||
|
@ -17,13 +17,6 @@ struct cfg_root : cfg::node
|
||||
bool has_rtm() const;
|
||||
|
||||
public:
|
||||
static constexpr bool thread_scheduler_enabled_def =
|
||||
#ifdef _WIN32
|
||||
true;
|
||||
#else
|
||||
false;
|
||||
#endif
|
||||
|
||||
node_core(cfg::node* _this) : cfg::node(_this, "Core") {}
|
||||
|
||||
cfg::_enum<ppu_decoder_type> ppu_decoder{ this, "PPU Decoder", ppu_decoder_type::llvm };
|
||||
@ -33,7 +26,7 @@ struct cfg_root : cfg::node
|
||||
cfg::string llvm_cpu{ this, "Use LLVM CPU" };
|
||||
cfg::_int<0, INT32_MAX> llvm_threads{ this, "Max LLVM Compile Threads", 0 };
|
||||
cfg::_bool ppu_llvm_greedy_mode{ this, "PPU LLVM Greedy Mode", false, false };
|
||||
cfg::_bool thread_scheduler_enabled{ this, "Enable thread scheduler", thread_scheduler_enabled_def };
|
||||
cfg::_enum<thread_scheduler_mode> thread_scheduler{this, "Thread Scheduler Mode", thread_scheduler_mode::os};
|
||||
cfg::_bool set_daz_and_ftz{ this, "Set DAZ and FTZ", false };
|
||||
cfg::_enum<spu_decoder_type> spu_decoder{ this, "SPU Decoder", spu_decoder_type::llvm };
|
||||
cfg::_bool lower_spu_priority{ this, "Lower SPU thread priority" };
|
||||
|
@ -436,3 +436,19 @@ void fmt_class_string<vk_gpu_scheduler_mode>::format(std::string& out, u64 arg)
|
||||
return unknown;
|
||||
});
|
||||
}
|
||||
|
||||
template <>
|
||||
void fmt_class_string<thread_scheduler_mode>::format(std::string& out, u64 arg)
|
||||
{
|
||||
format_enum(out, arg, [](thread_scheduler_mode value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case thread_scheduler_mode::old: return "RPCS3 Scheduler";
|
||||
case thread_scheduler_mode::alt: return "RPCS3 Alternative Scheduler";
|
||||
case thread_scheduler_mode::os: return "Operating System";
|
||||
}
|
||||
|
||||
return unknown;
|
||||
});
|
||||
}
|
||||
|
@ -201,3 +201,10 @@ enum class vk_gpu_scheduler_mode
|
||||
host,
|
||||
device
|
||||
};
|
||||
|
||||
enum class thread_scheduler_mode
|
||||
{
|
||||
os,
|
||||
old,
|
||||
alt
|
||||
};
|
||||
|
@ -831,6 +831,14 @@ QString emu_settings::GetLocalizedSetting(const QString& original, emu_settings_
|
||||
case spu_block_size_type::giga: return tr("Giga", "SPU block size");
|
||||
}
|
||||
break;
|
||||
case emu_settings_type::ThreadSchedulerMode:
|
||||
switch (static_cast<thread_scheduler_mode>(index))
|
||||
{
|
||||
case thread_scheduler_mode::old: return tr("RPCS3 Scheduler", "Thread Scheduler Mode");
|
||||
case thread_scheduler_mode::alt: return tr("RPCS3 Alternative Scheduler", "Thread Scheduler Mode");
|
||||
case thread_scheduler_mode::os: return tr("Operating System", "Thread Scheduler Mode");
|
||||
}
|
||||
break;
|
||||
case emu_settings_type::EnableTSX:
|
||||
switch (static_cast<tsx_usage>(index))
|
||||
{
|
||||
|
@ -11,7 +11,7 @@ enum class emu_settings_type
|
||||
PPUDecoder,
|
||||
SPUDecoder,
|
||||
HookStaticFuncs,
|
||||
EnableThreadScheduler,
|
||||
ThreadSchedulerMode,
|
||||
LowerSPUThreadPrio,
|
||||
SPULoopDetection,
|
||||
PreferredSPUThreads,
|
||||
@ -162,7 +162,7 @@ static const QMap<emu_settings_type, cfg_location> settings_location =
|
||||
{ emu_settings_type::PPUDecoder, { "Core", "PPU Decoder"}},
|
||||
{ emu_settings_type::SPUDecoder, { "Core", "SPU Decoder"}},
|
||||
{ emu_settings_type::HookStaticFuncs, { "Core", "Hook static functions"}},
|
||||
{ emu_settings_type::EnableThreadScheduler, { "Core", "Enable thread scheduler"}},
|
||||
{ emu_settings_type::ThreadSchedulerMode, { "Core", "Thread Scheduler Mode"}},
|
||||
{ emu_settings_type::LowerSPUThreadPrio, { "Core", "Lower SPU thread priority"}},
|
||||
{ emu_settings_type::SPULoopDetection, { "Core", "SPU loop detection"}},
|
||||
{ emu_settings_type::PreferredSPUThreads, { "Core", "Preferred SPU Threads"}},
|
||||
|
@ -193,9 +193,6 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> gui_settings, std
|
||||
m_emu_settings->EnhanceCheckBox(ui->spuCache, emu_settings_type::SPUCache);
|
||||
SubscribeTooltip(ui->spuCache, tooltips.settings.spu_cache);
|
||||
|
||||
m_emu_settings->EnhanceCheckBox(ui->enableScheduler, emu_settings_type::EnableThreadScheduler);
|
||||
SubscribeTooltip(ui->enableScheduler, tooltips.settings.enable_thread_scheduler);
|
||||
|
||||
m_emu_settings->EnhanceCheckBox(ui->lowerSPUThrPrio, emu_settings_type::LowerSPUThreadPrio);
|
||||
SubscribeTooltip(ui->lowerSPUThrPrio, tooltips.settings.lower_spu_thread_priority);
|
||||
|
||||
@ -210,6 +207,14 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> gui_settings, std
|
||||
m_emu_settings->EnhanceComboBox(ui->spuBlockSize, emu_settings_type::SPUBlockSize);
|
||||
SubscribeTooltip(ui->gb_spuBlockSize, tooltips.settings.spu_block_size);
|
||||
|
||||
m_emu_settings->EnhanceComboBox(ui->threadsched, emu_settings_type::ThreadSchedulerMode);
|
||||
SubscribeTooltip(ui->gb_threadsched, tooltips.settings.enable_thread_scheduler);
|
||||
if (u32 min_thread_count = 12; utils::get_thread_count() < min_thread_count)
|
||||
{
|
||||
ui->gb_threadsched->setDisabled(true);
|
||||
ui->gb_threadsched->setToolTip(tr("This feature is disabled for CPUs with less than %0 threads").arg(min_thread_count));
|
||||
}
|
||||
|
||||
m_emu_settings->EnhanceComboBox(ui->preferredSPUThreads, emu_settings_type::PreferredSPUThreads, true);
|
||||
SubscribeTooltip(ui->gb_spu_threads, tooltips.settings.preferred_spu_threads);
|
||||
ui->preferredSPUThreads->setItemText(ui->preferredSPUThreads->findData(0), tr("Auto", "Preferred SPU threads"));
|
||||
|
@ -143,13 +143,6 @@
|
||||
<string>Additional Settings</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="checkboxes_layout">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="enableScheduler">
|
||||
<property name="text">
|
||||
<string>Enable thread scheduler</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="lowerSPUThrPrio">
|
||||
<property name="text">
|
||||
@ -200,7 +193,7 @@
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="coreTabRightLayout" stretch="0,0,0,0">
|
||||
<layout class="QVBoxLayout" name="coreTabRightLayout" stretch="0,0,0,0,0">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="gb_tsx">
|
||||
<property name="sizePolicy">
|
||||
@ -255,6 +248,24 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="gb_threadsched">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Thread Scheduler</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="gb_threadsched_layout">
|
||||
<item>
|
||||
<widget class="QComboBox" name="threadsched"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="coreTabRightLayoutSpacer">
|
||||
<property name="orientation">
|
||||
|
@ -64,7 +64,7 @@ public:
|
||||
const QString spu_llvm = tr("Recompiles and caches the game's SPU code using the LLVM Recompiler before running which adds extra start-up time.\nThis is the fastest option with very good compatibility.\nIf you experience issues, use the ASMJIT Recompiler.");
|
||||
const QString accurate_xfloat = tr("Adds extra accuracy to SPU float vectors processing.\nFixes bugs in various games at the cost of performance.\nThis setting is only applied when SPU Decoder is set to Fast or LLVM.");
|
||||
const QString spu_cache = tr("Caches compiled SPU modules on disc.\nShould normally stay enabled.\nDisable this if the cache becomes too large.\nDisabling it does not remove the existing cache.");
|
||||
const QString enable_thread_scheduler = tr("Allows RPCS3 to manually schedule physical cores to run specific tasks on, instead of letting the OS handle it.\nVery useful on Windows, especially for AMD Ryzen systems where it can give huge performance gains.\nNote: This function is only implemented for AMD Ryzen CPUs.");
|
||||
const QString enable_thread_scheduler = tr("Control how RPCS3 utilizes the threads of your system, only useful for 6C/12T CPUs or higher up.\nEach option heavily depends on the game and on your CPU, it's recommended to try each option to find out which performs the best.");
|
||||
const QString lower_spu_thread_priority = tr("Runs SPU threads with lower priority than PPU threads.\nUsually faster on an i3 or i5, possibly slower or no difference on an i7 or Ryzen.");
|
||||
const QString spu_loop_detection = tr("Try to detect loop conditions in SPU kernels and use them as scheduling hints.\nImproves performance and reduces CPU usage.\nMay cause severe audio stuttering in rare cases.");
|
||||
const QString enable_tsx = tr("Enable usage of TSX instructions.\nNeeds to be forced on some Haswell or Broadwell CPUs.\nForcing this on older Hardware can lead to system instability, use it with caution.");
|
||||
|
Loading…
Reference in New Issue
Block a user