Skip to content

Commit b302e48

Browse files
committed
pin CPU thread to a fast core
1 parent 57dce8b commit b302e48

File tree

8 files changed

+61
-2
lines changed

8 files changed

+61
-2
lines changed

Source/Core/Common/ArmCPUDetect.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// SPDX-License-Identifier: GPL-2.0-or-later
33

44
#include "Common/CPUDetect.h"
5+
#include "Common/CPUDetectFastestCore.h"
56

67
#include <cstring>
78
#include <fstream>
@@ -224,6 +225,8 @@ void CPUInfo::Detect()
224225

225226
num_cores = std::max(static_cast<int>(std::thread::hardware_concurrency()), 1);
226227

228+
fastest_core = CPUDetectFastestCore(num_cores);
229+
227230
#ifdef __APPLE__
228231
SysctlByName(&model_name, "machdep.cpu.brand_string");
229232

Source/Core/Common/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ add_library(common
3737
Config/Layer.h
3838
Contains.h
3939
CPUDetect.h
40+
CPUDetectFastestCore.h
4041
Crypto/AES.cpp
4142
Crypto/AES.h
4243
Crypto/bn.cpp

Source/Core/Common/CPUDetect.h

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ struct CPUInfo
2323

2424
bool HTT = false;
2525
int num_cores = 0;
26+
int fastest_core = 0;
2627

2728
bool bSSE3 = false;
2829
bool bSSSE3 = false;
+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright 2013 Dolphin Emulator Project
2+
// SPDX-License-Identifier: GPL-2.0-or-later
3+
4+
#include <fstream>
5+
#include <sstream>
6+
#include <string>
7+
8+
#include "Common/CommonTypes.h"
9+
#include "Common/FileUtil.h"
10+
11+
static int CPUDetectFastestCore(int num_cores)
12+
{
13+
int fastest_core = 0;
14+
u32 fastest_freq = 0;
15+
#ifdef __linux__
16+
std::ostringstream ss;
17+
for (int i = 0; i < num_cores; i++)
18+
{
19+
ss.str("/sys/devices/system/cpu/cpu");
20+
ss << i << "/cpufreq/cpuinfo_max_freq";
21+
22+
std::ifstream file;
23+
File::OpenFStream(file, ss.str(), std::ios_base::in);
24+
if (!file)
25+
continue;
26+
27+
u32 freq;
28+
file >> freq;
29+
if (freq > fastest_freq)
30+
{
31+
fastest_freq = freq;
32+
fastest_core = i;
33+
}
34+
}
35+
#else
36+
// TODO
37+
#endif
38+
return fastest_core;
39+
}

Source/Core/Common/Thread.cpp

+5-2
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,7 @@ void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask)
122122
{
123123
#ifdef __APPLE__
124124
thread_policy_set(pthread_mach_thread_np(thread), THREAD_AFFINITY_POLICY, (integer_t*)&mask, 1);
125-
#elif (defined __linux__ || defined BSD4_4 || defined __FreeBSD__ || defined __NetBSD__) && \
126-
!(defined ANDROID)
125+
#elif (defined __linux__ || defined BSD4_4 || defined __FreeBSD__ || defined __NetBSD__)
127126
#ifndef __NetBSD__
128127
#ifdef __FreeBSD__
129128
cpuset_t cpu_set;
@@ -136,7 +135,11 @@ void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask)
136135
if ((mask >> i) & 1)
137136
CPU_SET(i, &cpu_set);
138137

138+
#ifdef ANDROID
139+
sched_setaffinity(pthread_gettid_np(thread), sizeof(cpu_set), &cpu_set);
140+
#else
139141
pthread_setaffinity_np(thread, sizeof(cpu_set), &cpu_set);
142+
#endif
140143
#else
141144
cpuset_t* cpu_set = cpuset_create();
142145

Source/Core/Common/x64CPUDetect.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// SPDX-License-Identifier: GPL-2.0-or-later
33

44
#include "Common/CPUDetect.h"
5+
#include "Common/CPUDetectFastestCore.h"
56

67
#ifdef _WIN32
78
#include <windows.h>
@@ -117,6 +118,8 @@ void CPUInfo::Detect()
117118
// CPUID data ourselves.
118119
num_cores = std::max(static_cast<int>(std::thread::hardware_concurrency()), 1);
119120

121+
fastest_core = CPUDetectFastestCore(num_cores); // TODO: cpuid?
122+
120123
// Assume CPU supports the CPUID instruction. Those that don't can barely
121124
// boot modern OS anyway.
122125

Source/Core/Core/HW/CPU.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include "AudioCommon/AudioCommon.h"
1111
#include "Common/CommonTypes.h"
12+
#include "Common/CPUDetect.h"
1213
#include "Common/Event.h"
1314
#include "Common/Thread.h"
1415
#include "Common/Timer.h"
@@ -120,6 +121,13 @@ void CPUManager::Run()
120121
timing = std::thread(&CPUManager::StartTimePlayedTimer, this);
121122
}
122123

124+
// Pin the thread to the fastest core
125+
// if (Config::Get(Config::MAIN_THREAD_PINNING)) // TODO
126+
{
127+
u32 mask = static_cast<u32>(1) << cpu_info.fastest_core;
128+
Thread::SetCurrentThreadAffinity(mask);
129+
}
130+
123131
std::unique_lock state_lock(m_state_change_lock);
124132
while (m_state != State::PowerDown)
125133
{

Source/Core/DolphinLib.props

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
<ClInclude Include="Common\Config\Layer.h" />
4141
<ClInclude Include="Common\Contains.h" />
4242
<ClInclude Include="Common\CPUDetect.h" />
43+
<ClInclude Include="Common\CPUDetectFastestCore.h" />
4344
<ClInclude Include="Common\Crypto\AES.h" />
4445
<ClInclude Include="Common\Crypto\bn.h" />
4546
<ClInclude Include="Common\Crypto\ec.h" />

0 commit comments

Comments
 (0)