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;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
// 1700, 1800, 2700, TR 1900X family
|
// 1700, 1800, 2700, TR 1900X family
|
||||||
ppu_mask = 0b1111111100000000;
|
if (g_cfg.core.thread_scheduler == thread_scheduler_mode::alt)
|
||||||
spu_mask = ppu_mask;
|
{
|
||||||
rsx_mask = 0b0000000000111100;
|
ppu_mask = 0b0010000010000000;
|
||||||
|
spu_mask = 0b0000101010101010;
|
||||||
|
rsx_mask = 0b1000000000000000;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ppu_mask = 0b1111111100000000;
|
||||||
|
spu_mask = ppu_mask;
|
||||||
|
rsx_mask = 0b0000000000111100;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 12:
|
case 12:
|
||||||
// 1600, 2600 family, Assign threads 3-12
|
// 1600, 2600 family, Assign threads 3-12
|
||||||
@ -2739,16 +2748,36 @@ u64 thread_ctrl::get_affinity_mask(thread_class group)
|
|||||||
spu_mask = 0b000000111111000000000000;
|
spu_mask = 0b000000111111000000000000;
|
||||||
rsx_mask = 0b000000000000111111000000;
|
rsx_mask = 0b000000000000111111000000;
|
||||||
break;
|
break;
|
||||||
default:
|
case 16:
|
||||||
if (thread_count >= 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
|
// Verified by more than one windows user on 16-thread CPU
|
||||||
ppu_mask = spu_mask = rsx_mask = (0b10101010101010101010101010101010 & all_cores_mask);
|
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
|
else
|
||||||
{
|
{
|
||||||
ppu_mask = spu_mask = rsx_mask = all_cores_mask;
|
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;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2774,23 +2803,8 @@ u64 thread_ctrl::get_affinity_mask(thread_class group)
|
|||||||
}
|
}
|
||||||
case native_core_arrangement::intel_ht:
|
case native_core_arrangement::intel_ht:
|
||||||
{
|
{
|
||||||
/* This has been disabled as it seems to degrade performance instead of improving it.
|
if (thread_count >= 12 && g_cfg.core.thread_scheduler == thread_scheduler_mode::alt)
|
||||||
if (thread_count <= 4)
|
return (0b10101010101010101010101010101010 & all_cores_mask); // Potentially improves performance by mimicking HT off
|
||||||
{
|
|
||||||
//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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
return all_cores_mask;
|
return all_cores_mask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -405,7 +405,7 @@ void cpu_thread::operator()()
|
|||||||
{
|
{
|
||||||
g_tls_this_thread = this;
|
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));
|
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();
|
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));
|
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
|
// Raise priority above other threads
|
||||||
thread_ctrl::scoped_priority high_prio(+1);
|
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));
|
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;
|
bool has_rtm() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static constexpr bool thread_scheduler_enabled_def =
|
|
||||||
#ifdef _WIN32
|
|
||||||
true;
|
|
||||||
#else
|
|
||||||
false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
node_core(cfg::node* _this) : cfg::node(_this, "Core") {}
|
node_core(cfg::node* _this) : cfg::node(_this, "Core") {}
|
||||||
|
|
||||||
cfg::_enum<ppu_decoder_type> ppu_decoder{ this, "PPU Decoder", ppu_decoder_type::llvm };
|
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::string llvm_cpu{ this, "Use LLVM CPU" };
|
||||||
cfg::_int<0, INT32_MAX> llvm_threads{ this, "Max LLVM Compile Threads", 0 };
|
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 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::_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::_enum<spu_decoder_type> spu_decoder{ this, "SPU Decoder", spu_decoder_type::llvm };
|
||||||
cfg::_bool lower_spu_priority{ this, "Lower SPU thread priority" };
|
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;
|
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,
|
host,
|
||||||
device
|
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");
|
case spu_block_size_type::giga: return tr("Giga", "SPU block size");
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case emu_settings_type::EnableTSX:
|
||||||
switch (static_cast<tsx_usage>(index))
|
switch (static_cast<tsx_usage>(index))
|
||||||
{
|
{
|
||||||
|
@ -11,7 +11,7 @@ enum class emu_settings_type
|
|||||||
PPUDecoder,
|
PPUDecoder,
|
||||||
SPUDecoder,
|
SPUDecoder,
|
||||||
HookStaticFuncs,
|
HookStaticFuncs,
|
||||||
EnableThreadScheduler,
|
ThreadSchedulerMode,
|
||||||
LowerSPUThreadPrio,
|
LowerSPUThreadPrio,
|
||||||
SPULoopDetection,
|
SPULoopDetection,
|
||||||
PreferredSPUThreads,
|
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::PPUDecoder, { "Core", "PPU Decoder"}},
|
||||||
{ emu_settings_type::SPUDecoder, { "Core", "SPU Decoder"}},
|
{ emu_settings_type::SPUDecoder, { "Core", "SPU Decoder"}},
|
||||||
{ emu_settings_type::HookStaticFuncs, { "Core", "Hook static functions"}},
|
{ 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::LowerSPUThreadPrio, { "Core", "Lower SPU thread priority"}},
|
||||||
{ emu_settings_type::SPULoopDetection, { "Core", "SPU loop detection"}},
|
{ emu_settings_type::SPULoopDetection, { "Core", "SPU loop detection"}},
|
||||||
{ emu_settings_type::PreferredSPUThreads, { "Core", "Preferred SPU Threads"}},
|
{ 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);
|
m_emu_settings->EnhanceCheckBox(ui->spuCache, emu_settings_type::SPUCache);
|
||||||
SubscribeTooltip(ui->spuCache, tooltips.settings.spu_cache);
|
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);
|
m_emu_settings->EnhanceCheckBox(ui->lowerSPUThrPrio, emu_settings_type::LowerSPUThreadPrio);
|
||||||
SubscribeTooltip(ui->lowerSPUThrPrio, tooltips.settings.lower_spu_thread_priority);
|
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);
|
m_emu_settings->EnhanceComboBox(ui->spuBlockSize, emu_settings_type::SPUBlockSize);
|
||||||
SubscribeTooltip(ui->gb_spuBlockSize, tooltips.settings.spu_block_size);
|
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);
|
m_emu_settings->EnhanceComboBox(ui->preferredSPUThreads, emu_settings_type::PreferredSPUThreads, true);
|
||||||
SubscribeTooltip(ui->gb_spu_threads, tooltips.settings.preferred_spu_threads);
|
SubscribeTooltip(ui->gb_spu_threads, tooltips.settings.preferred_spu_threads);
|
||||||
ui->preferredSPUThreads->setItemText(ui->preferredSPUThreads->findData(0), tr("Auto", "Preferred SPU threads"));
|
ui->preferredSPUThreads->setItemText(ui->preferredSPUThreads->findData(0), tr("Auto", "Preferred SPU threads"));
|
||||||
|
@ -143,13 +143,6 @@
|
|||||||
<string>Additional Settings</string>
|
<string>Additional Settings</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="checkboxes_layout">
|
<layout class="QVBoxLayout" name="checkboxes_layout">
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="enableScheduler">
|
|
||||||
<property name="text">
|
|
||||||
<string>Enable thread scheduler</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="lowerSPUThrPrio">
|
<widget class="QCheckBox" name="lowerSPUThrPrio">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@ -200,7 +193,7 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="coreTabRightLayout" stretch="0,0,0,0">
|
<layout class="QVBoxLayout" name="coreTabRightLayout" stretch="0,0,0,0,0">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="gb_tsx">
|
<widget class="QGroupBox" name="gb_tsx">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
@ -255,6 +248,24 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</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>
|
<item>
|
||||||
<spacer name="coreTabRightLayoutSpacer">
|
<spacer name="coreTabRightLayoutSpacer">
|
||||||
<property name="orientation">
|
<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 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 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 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 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 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.");
|
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