Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VMManager: Refactor Affinity Control to Thread Pinning #11403

Merged
merged 1 commit into from
Jun 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions pcsx2-qt/Settings/AdvancedSettingsWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ AdvancedSettingsWidget::AdvancedSettingsWidget(SettingsWindow* dialog, QWidget*
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.vu0Recompiler, "EmuCore/CPU/Recompiler", "EnableVU0", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.vu1Recompiler, "EmuCore/CPU/Recompiler", "EnableVU1", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.vuFlagHack, "EmuCore/Speedhacks", "vuFlagHack", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.instantVU1, "EmuCore/Speedhacks", "vu1Instant", true);

SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.eeRoundingMode, "EmuCore/CPU", "FPU.Roundmode", static_cast<int>(FPRoundMode::ChopZero));
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.eeDivRoundingMode, "EmuCore/CPU", "FPUDiv.Roundmode", static_cast<int>(FPRoundMode::Nearest));
Expand Down Expand Up @@ -101,6 +102,9 @@ AdvancedSettingsWidget::AdvancedSettingsWidget(SettingsWindow* dialog, QWidget*
dialog->registerWidgetHelp(m_ui.vu1ClampMode, tr("VU1 Clamping Mode"), tr("Normal (Default)"), tr("Changes how PCSX2 handles keeping floats in a standard x86 range in the Emotion Engine's Vector Unit 1 (EE VU1). "
"The default value handles the vast majority of games; <b>modifying this setting when a game is not having a visible problem can cause instability.</b>"));

dialog->registerWidgetHelp(m_ui.instantVU1, tr("Enable Instant VU1"), tr("Checked"), tr("Runs VU1 instantly. Provides a modest speed improvement in most games. "
"Safe for most games, but a few games may exhibit graphical errors."));

//: VU0 = Vector Unit 0. One of the PS2's processors.
dialog->registerWidgetHelp(m_ui.vu0Recompiler, tr("Enable VU0 Recompiler (Micro Mode)"), tr("Checked"), tr("Enables VU0 Recompiler."));

Expand Down
15 changes: 11 additions & 4 deletions pcsx2-qt/Settings/AdvancedSettingsWidget.ui
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>807</width>
<height>723</height>
<width>790</width>
<height>765</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
Expand Down Expand Up @@ -202,7 +202,7 @@
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="extraMemory">
<property name="text">
<property name="text">
<string>Enable 128MB RAM (Dev Console)</string>
</property>
</widget>
Expand Down Expand Up @@ -272,6 +272,13 @@
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="instantVU1">
<property name="text">
<string>Enable Instant VU1</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="1">
Expand Down Expand Up @@ -494,7 +501,7 @@
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
Expand Down
8 changes: 2 additions & 6 deletions pcsx2-qt/Settings/EmulationSettingsWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,9 @@ EmulationSettingsWidget::EmulationSettingsWidget(SettingsWindow* dialog, QWidget
m_ui.optimalFramePacing->setTristate(dialog->isPerGameSettings());

SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.eeCycleSkipping, "EmuCore/Speedhacks", "EECycleSkip", DEFAULT_EE_CYCLE_SKIP);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.affinityControl, "EmuCore/CPU", "AffinityControlMode", 0);

SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.MTVU, "EmuCore/Speedhacks", "vuThread", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.instantVU1, "EmuCore/Speedhacks", "vu1Instant", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.threadPinning, "EmuCore", "EnableThreadPinning", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.fastCDVD, "EmuCore/Speedhacks", "fastCDVD", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.precacheCDVD, "EmuCore", "CdvdPrecache", false);

Expand Down Expand Up @@ -113,16 +112,13 @@ EmulationSettingsWidget::EmulationSettingsWidget(SettingsWindow* dialog, QWidget
tr("Makes the emulated Emotion Engine skip cycles. "
//: SOTC = Shadow of the Colossus. A game's title, should not be translated unless an official translation exists.
"Helps a small subset of games like SOTC. Most of the time it's harmful to performance."));
dialog->registerWidgetHelp(m_ui.affinityControl, tr("Affinity Control"), tr("Disabled"),
dialog->registerWidgetHelp(m_ui.threadPinning, tr("Enable Thread Pinning"), tr("Unchecked"),
tr("Sets the priority for specific threads in a specific order ignoring the system scheduler. "
//: P-Core = Performance Core, E-Core = Efficiency Core. See if Intel has official translations for these terms.
"May help CPUs with big (P) and little (E) cores (e.g. Intel 12th or newer generation CPUs from Intel or other vendors such as AMD)."));
dialog->registerWidgetHelp(m_ui.MTVU, tr("Enable Multithreaded VU1 (MTVU1)"), tr("Checked"),
tr("Generally a speedup on CPUs with 4 or more cores. "
"Safe for most games, but a few are incompatible and may hang."));
dialog->registerWidgetHelp(m_ui.instantVU1, tr("Enable Instant VU1"), tr("Checked"),
tr("Runs VU1 instantly. Provides a modest speed improvement in most games. "
"Safe for most games, but a few games may exhibit graphical errors."));
dialog->registerWidgetHelp(m_ui.fastCDVD, tr("Enable Fast CDVD"), tr("Unchecked"),
tr("Fast disc access, less loading times. Check HDLoader compatibility lists for known games that have issues with this."));
dialog->registerWidgetHelp(m_ui.precacheCDVD, tr("Enable CDVD Precaching"), tr("Unchecked"),
Expand Down
170 changes: 62 additions & 108 deletions pcsx2-qt/Settings/EmulationSettingsWidget.ui
Original file line number Diff line number Diff line change
Expand Up @@ -68,90 +68,6 @@
<string>System Settings</string>
</property>
<layout class="QGridLayout" name="gridLayout_5">
<item row="3" column="0" colspan="2">
<layout class="QGridLayout" name="systemSettingsLayout">
<item row="0" column="1">
<widget class="QCheckBox" name="instantVU1">
<property name="text">
<string>Enable Instant VU1</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="cheats">
<property name="text">
<string>Enable Cheats</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="MTVU">
<property name="text">
<string>Enable Multithreaded VU1 (MTVU)</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="hostFilesystem">
<property name="text">
<string>Enable Host Filesystem</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="fastCDVD">
<property name="text">
<string>Enable Fast CDVD</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="precacheCDVD">
<property name="text">
<string>Enable CDVD Precaching</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>EE Cycle Skipping:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="eeCycleSkipping">
<item>
<property name="text">
<string>Disabled</string>
</property>
</item>
<item>
<property name="text">
<string>Mild Underclock</string>
</property>
</item>
<item>
<property name="text">
<string>Moderate Underclock</string>
</property>
</item>
<item>
<property name="text">
<string>Maximum Underclock</string>
</property>
</item>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>EE Cycle Rate:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="eeCycleRate">
<item>
Expand Down Expand Up @@ -191,50 +107,88 @@
</item>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Affinity Control:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="affinityControl">
<item row="1" column="1">
<widget class="QComboBox" name="eeCycleSkipping">
<item>
<property name="text">
<string>Disabled</string>
</property>
</item>
<item>
<property name="text">
<string>EE &gt; VU &gt; GS</string>
<string>Mild Underclock</string>
</property>
</item>
<item>
<property name="text">
<string>EE &gt; GS &gt; VU</string>
<string>Moderate Underclock</string>
</property>
</item>
<item>
<property name="text">
<string>VU &gt; EE &gt; GS</string>
<string>Maximum Underclock</string>
</property>
</item>
<item>
<property name="text">
<string>VU &gt; GS &gt; EE</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<layout class="QGridLayout" name="systemSettingsLayout">
<item row="1" column="0">
<widget class="QCheckBox" name="cheats">
<property name="text">
<string>Enable Cheats</string>
</property>
</widget>
</item>
<item>
<property name="text">
<string>GS &gt; EE &gt; VU</string>
</property>
<item row="0" column="0">
<widget class="QCheckBox" name="MTVU">
<property name="text">
<string>Enable Multithreaded VU1 (MTVU)</string>
</property>
</widget>
</item>
<item>
<property name="text">
<string>GS &gt; VU &gt; EE</string>
</property>
<item row="1" column="1">
<widget class="QCheckBox" name="hostFilesystem">
<property name="text">
<string>Enable Host Filesystem</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="fastCDVD">
<property name="text">
<string>Enable Fast CDVD</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="precacheCDVD">
<property name="text">
<string>Enable CDVD Precaching</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="threadPinning">
<property name="text">
<string>Enable Thread Pinning</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>EE Cycle Rate:</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>EE Cycle Skipping:</string>
</property>
</widget>
</item>
</layout>
Expand Down
3 changes: 1 addition & 2 deletions pcsx2/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -545,8 +545,6 @@ struct Pcsx2Config
FPControlRegister VU0FPCR;
FPControlRegister VU1FPCR;

u32 AffinityControlMode;

CpuOptions();
void LoadSave(SettingsWrapper& wrap);
void ApplySanityCheck();
Expand Down Expand Up @@ -1119,6 +1117,7 @@ struct Pcsx2Config
EnableNoInterlacingPatches : 1,
EnableFastBoot : 1,
EnableFastBootFastForward : 1,
EnableThreadPinning : 1,
// TODO - Vaser - where are these settings exposed in the Qt UI?
EnableRecordingTools : 1,
EnableGameFixes : 1, // enables automatic game fixes
Expand Down
25 changes: 12 additions & 13 deletions pcsx2/GS/Renderers/SW/GSRasterizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1209,23 +1209,15 @@ GSRasterizerList::~GSRasterizerList()
_aligned_free(m_scanline);
}

void GSRasterizerList::OnWorkerStartup(int i)
void GSRasterizerList::OnWorkerStartup(int i, u64 affinity)
{
Threading::SetNameOfCurrentThread(StringUtil::StdStringFromFormat("GS-SW-%d", i).c_str());

Threading::ThreadHandle handle(Threading::ThreadHandle::GetForCallingThread());

if (EmuConfig.Cpu.AffinityControlMode != 0)
if (affinity != 0)
{
const std::vector<u32>& procs = VMManager::GetSortedProcessorList();
const u32 processor_index = (THREAD_VU1 ? 3 : 2) + i;
if (processor_index < procs.size())
{
const u32 procid = procs[processor_index];
const u64 affinity = static_cast<u64>(1) << procid;
Console.WriteLn("Pinning GS thread %d to CPU %u (0x%llx)", i, procid, affinity);
handle.SetAffinity(affinity);
}
INFO_LOG("Pinning GS thread {} to CPU {} (0x{:x})", i, std::countr_zero(affinity), affinity);
handle.SetAffinity(affinity);
}

PerformanceMetrics::SetGSSWThread(i, std::move(handle));
Expand Down Expand Up @@ -1306,11 +1298,18 @@ std::unique_ptr<IRasterizer> GSRasterizerList::Create(int threads)

std::unique_ptr<GSRasterizerList> rl(new GSRasterizerList(threads));

const std::vector<u32>& procs = VMManager::Internal::GetSoftwareRendererProcessorList();
const bool pin = (EmuConfig.EnableThreadPinning && static_cast<size_t>(threads) <= procs.size());
if (EmuConfig.EnableThreadPinning && !pin)
WARNING_LOG("Not pinning SW threads, we need {} processors, but only have {}", threads, procs.size());

for (int i = 0; i < threads; i++)
{
const u64 affinity = pin ? (static_cast<u64>(1u) << procs[i]) : 0;
rl->m_r.push_back(std::unique_ptr<GSRasterizer>(new GSRasterizer(&rl->m_ds, i, threads)));
auto& r = *rl->m_r[i];
rl->m_workers.push_back(std::unique_ptr<GSWorker>(new GSWorker([i]() { GSRasterizerList::OnWorkerStartup(i); },
rl->m_workers.push_back(std::unique_ptr<GSWorker>(new GSWorker(
[i, affinity]() { GSRasterizerList::OnWorkerStartup(i, affinity); },
[&r](GSRingHeap::SharedPtr<GSRasterizerData>& item) { r.Draw(*item.get()); },
[i]() { GSRasterizerList::OnWorkerShutdown(i); })));
}
Expand Down
2 changes: 1 addition & 1 deletion pcsx2/GS/Renderers/SW/GSRasterizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ class GSRasterizerList final : public IRasterizer

GSRasterizerList(int threads);

static void OnWorkerStartup(int i);
static void OnWorkerStartup(int i, u64 affinity);
static void OnWorkerShutdown(int i);

public:
Expand Down
Loading