Skip to content

Commit d04c92b

Browse files
authored
Reimplement CPU Affinity (#4110)
1 parent 372b1e5 commit d04c92b

File tree

4 files changed

+100
-4
lines changed

4 files changed

+100
-4
lines changed

Client/core/CClientVariables.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,7 @@ void CClientVariables::LoadDefaults()
357357
DEFAULT("discord_rpc_share_data", false); // Consistent Rich Presence data sharing
358358
DEFAULT("discord_rpc_share_data_firsttime", false); // Display the user data sharing consent dialog box - for the first time
359359
DEFAULT("browser_enable_gpu", true); // Enable GPU in CEF? (allows stuff like WebGL to function)
360+
DEFAULT("process_cpu_affinity", false); // Set CPU 0 affinity to improve game performance and fix the known issue in single-threaded games
360361

361362
if (!Exists("locale"))
362363
{

Client/core/CCore.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1795,6 +1795,17 @@ void CCore::ApplyCoreInitSettings()
17951795

17961796
SetApplicationSettingInt("reset-settings-revision", 21486);
17971797
}
1798+
1799+
// Set process settings
1800+
HANDLE currProc = GetCurrentProcess();
1801+
1802+
// Process priority
1803+
int PriorityClassList[] = {NORMAL_PRIORITY_CLASS, ABOVE_NORMAL_PRIORITY_CLASS, HIGH_PRIORITY_CLASS};
1804+
SetPriorityClass(currProc, PriorityClassList[CVARS_GET_VALUE<int>("process_priority") % 3]);
1805+
1806+
// Process CPU affinity
1807+
if (CVARS_GET_VALUE<bool>("process_cpu_affinity"))
1808+
SetProcessAffinityMask(currProc, 1 << 0);
17981809
}
17991810

18001811
//

Client/core/CSettings.cpp

Lines changed: 86 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,12 @@ void CSettings::CreateGUI()
405405
m_pCheckBoxAllowDiscordRPC->GetPosition(vecTemp, false);
406406
m_pCheckBoxAllowDiscordRPC->AutoSize(NULL, 20.0f);
407407

408+
// Enable camera photos getting saved to documents folder
409+
m_pPhotoSavingCheckbox = reinterpret_cast<CGUICheckBox*>(pManager->CreateCheckBox(pTabMultiplayer, _("Save photos taken by camera weapon to GTA San Andreas User Files folder"), true));
410+
m_pPhotoSavingCheckbox->SetPosition(CVector2D(vecTemp.fX, vecTemp.fY + 20.0f));
411+
m_pPhotoSavingCheckbox->GetPosition(vecTemp, false);
412+
m_pPhotoSavingCheckbox->AutoSize(NULL, 20.0f);
413+
408414
m_pCheckBoxCustomizedSAFiles = reinterpret_cast<CGUICheckBox*>(pManager->CreateCheckBox(pTabMultiplayer, _("Use customized GTA:SA files"), true));
409415
m_pCheckBoxCustomizedSAFiles->SetPosition(CVector2D(vecTemp.fX, vecTemp.fY + 20.0f));
410416
m_pCheckBoxCustomizedSAFiles->GetPosition(vecTemp, false);
@@ -1201,10 +1207,10 @@ void CSettings::CreateGUI()
12011207
m_pCachePathValue->AutoSize();
12021208
vecTemp.fY += fLineHeight;
12031209

1204-
// Enable camera photos getting saved to documents folder
1205-
m_pPhotoSavingCheckbox = reinterpret_cast<CGUICheckBox*>(pManager->CreateCheckBox(pTabAdvanced, _("Save photos taken by camera weapon to GTA San Andreas User Files folder"), true));
1206-
m_pPhotoSavingCheckbox->SetPosition(CVector2D(vecTemp.fX, vecTemp.fY));
1207-
m_pPhotoSavingCheckbox->AutoSize(NULL, 20.0f);
1210+
// Process affinity
1211+
m_pProcessAffinityCheckbox = reinterpret_cast<CGUICheckBox*>(pManager->CreateCheckBox(pTabAdvanced, _("Set CPU 0 affinity to improve game performance"), true));
1212+
m_pProcessAffinityCheckbox->SetPosition(CVector2D(vecTemp.fX, vecTemp.fY));
1213+
m_pProcessAffinityCheckbox->AutoSize(nullptr, 20.0f);
12081214
vecTemp.fY += fLineHeight;
12091215

12101216
// Auto updater section label
@@ -1306,6 +1312,7 @@ void CSettings::CreateGUI()
13061312
m_pButtonBrowserWhitelistRemove->SetClickHandler(GUI_CALLBACK(&CSettings::OnBrowserWhitelistRemove, this));
13071313
m_pEditBrowserWhitelistAdd->SetActivateHandler(GUI_CALLBACK(&CSettings::OnBrowserWhitelistDomainAddFocused, this));
13081314
m_pEditBrowserWhitelistAdd->SetDeactivateHandler(GUI_CALLBACK(&CSettings::OnBrowserWhitelistDomainAddDefocused, this));
1315+
m_pProcessAffinityCheckbox->SetClickHandler(GUI_CALLBACK(&CSettings::OnAffinityClick, this));
13091316

13101317
// Set up the events for advanced description
13111318
m_pPriorityLabel->SetMouseEnterHandler(GUI_CALLBACK(&CSettings::OnShowAdvancedSettingDescription, this));
@@ -1374,6 +1381,9 @@ void CSettings::CreateGUI()
13741381
m_pUpdateAutoInstallCombo->SetMouseEnterHandler(GUI_CALLBACK(&CSettings::OnShowAdvancedSettingDescription, this));
13751382
m_pUpdateAutoInstallCombo->SetMouseLeaveHandler(GUI_CALLBACK(&CSettings::OnHideAdvancedSettingDescription, this));
13761383

1384+
m_pProcessAffinityCheckbox->SetMouseEnterHandler(GUI_CALLBACK(&CSettings::OnShowAdvancedSettingDescription, this));
1385+
m_pProcessAffinityCheckbox->SetMouseLeaveHandler(GUI_CALLBACK(&CSettings::OnHideAdvancedSettingDescription, this));
1386+
13771387
// Load Chat presets
13781388
LoadChatPresets();
13791389

@@ -3228,6 +3238,22 @@ void CSettings::LoadData()
32283238
CVARS_GET("photosaving", bVar);
32293239
m_pPhotoSavingCheckbox->SetSelected(bVar);
32303240

3241+
// Process CPU Affinity
3242+
CVARS_GET("process_cpu_affinity", bVar);
3243+
m_pProcessAffinityCheckbox->SetSelected(bVar);
3244+
3245+
DWORD_PTR affinityMask = 0;
3246+
if (bVar)
3247+
affinityMask = 1 << 0; // CPU 0 only
3248+
else
3249+
{
3250+
SYSTEM_INFO sysInfo;
3251+
GetSystemInfo(&sysInfo);
3252+
3253+
affinityMask = (1 << sysInfo.dwNumberOfProcessors) - 1; // All cores (default)
3254+
}
3255+
SetProcessAffinityMask(GetCurrentProcess(), affinityMask);
3256+
32313257
// Update build type
32323258
CVARS_GET("update_build_type", iVar);
32333259
if (iVar == 0 || iVar == 1)
@@ -3624,6 +3650,22 @@ void CSettings::SaveData()
36243650
CVARS_SET("photosaving", photoSaving);
36253651
CScreenShot::SetPhotoSavingInsideDocuments(photoSaving);
36263652

3653+
// Process CPU Affinity
3654+
bool cpuAffinity = m_pProcessAffinityCheckbox->GetSelected();
3655+
CVARS_SET("process_cpu_affinity", cpuAffinity);
3656+
3657+
DWORD_PTR affinityMask = 0;
3658+
if (cpuAffinity)
3659+
affinityMask = 1 << 0; // CPU 0 only
3660+
else
3661+
{
3662+
SYSTEM_INFO sysInfo;
3663+
GetSystemInfo(&sysInfo);
3664+
3665+
affinityMask = (1 << sysInfo.dwNumberOfProcessors) - 1; // All cores (default)
3666+
}
3667+
SetProcessAffinityMask(GetCurrentProcess(), affinityMask);
3668+
36273669
// Debug setting
36283670
if (CGUIListItem* pSelected = m_pDebugSettingCombo->GetSelectedItem())
36293671
{
@@ -4711,6 +4753,44 @@ static void DPIAwareQuestionCallBack(void* userdata, unsigned int uiButton)
47114753
}
47124754
}
47134755

4756+
static void CPUAffinityQuestionCallBack(void* userdata, unsigned int button)
4757+
{
4758+
CCore::GetSingleton().GetLocalGUI()->GetMainMenu()->GetQuestionWindow()->Reset();
4759+
4760+
if (button == 0)
4761+
{
4762+
auto const checkBox = reinterpret_cast<CGUICheckBox*>(userdata);
4763+
checkBox->SetSelected(false);
4764+
}
4765+
}
4766+
4767+
bool CSettings::OnAffinityClick(CGUIElement* pElement)
4768+
{
4769+
static bool shownWarning = false;
4770+
4771+
if (m_pProcessAffinityCheckbox->GetSelected() && !shownWarning)
4772+
{
4773+
shownWarning = true;
4774+
4775+
std::string message = std::string(
4776+
_("Enabling this setting may improve game performance, but on some processors, it may worsen it.\n"
4777+
"We have observed issues with AMD Ryzen processors featuring 3D V-Cache.\n"
4778+
"The exact list of affected processors is unknown.\n"
4779+
"\nAre you sure you want to enable this option?"));
4780+
4781+
CQuestionBox* pQuestionBox = CCore::GetSingleton().GetLocalGUI()->GetMainMenu()->GetQuestionWindow();
4782+
pQuestionBox->Reset();
4783+
pQuestionBox->SetTitle(_("EXPERIMENTAL FEATURE"));
4784+
pQuestionBox->SetMessage(message);
4785+
pQuestionBox->SetButton(0, _("No"));
4786+
pQuestionBox->SetButton(1, _("Yes"));
4787+
pQuestionBox->SetCallback(CPUAffinityQuestionCallBack, m_pProcessAffinityCheckbox);
4788+
pQuestionBox->Show();
4789+
}
4790+
4791+
return true;
4792+
}
4793+
47144794
bool CSettings::OnBrowserBlacklistAdd(CGUIElement* pElement)
47154795
{
47164796
SString strDomain = m_pEditBrowserBlacklistAdd->GetText();
@@ -4874,6 +4954,8 @@ bool CSettings::OnShowAdvancedSettingDescription(CGUIElement* pElement)
48744954
strText = std::string(_("16-bit color:")) + " " + std::string(_("Enable 16 bit color modes - Requires MTA restart"));
48754955
else if (pCheckBox && pCheckBox == m_pWin8MouseCheckBox)
48764956
strText = std::string(_("Mouse fix:")) + " " + std::string(_("Mouse movement fix - May need PC restart"));
4957+
else if (pCheckBox && pCheckBox == m_pProcessAffinityCheckbox)
4958+
strText = std::string(_("CPU affinity:")) + " " + std::string(_("Experimental feature - It may improve performance or worsen it."));
48774959

48784960
if (strText != "")
48794961
m_pAdvancedSettingDescriptionLabel->SetText(strText.c_str());

Client/core/CSettings.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ class CSettings
216216
CGUICheckBox* m_pWin8ColorCheckBox;
217217
CGUICheckBox* m_pWin8MouseCheckBox;
218218
CGUICheckBox* m_pPhotoSavingCheckbox;
219+
CGUICheckBox* m_pProcessAffinityCheckbox;
219220
CGUILabel* m_pUpdateBuildTypeLabel;
220221
CGUIComboBox* m_pUpdateBuildTypeCombo;
221222
CGUILabel* m_pUpdateAutoInstallLabel;
@@ -406,6 +407,7 @@ class CSettings
406407
bool OnShowAdvancedSettingDescription(CGUIElement* pElement);
407408
bool OnHideAdvancedSettingDescription(CGUIElement* pElement);
408409
bool OnTabChanged(CGUIElement* pElement);
410+
bool OnAffinityClick(CGUIElement* pElement);
409411
void ReloadBrowserLists();
410412

411413
private:

0 commit comments

Comments
 (0)