diff options
| author | 2018-05-03 00:34:54 -0400 | |
|---|---|---|
| committer | 2018-05-10 19:34:47 -0400 | |
| commit | 9bf2a428f9e9359763be1bfd90c32371044c711e (patch) | |
| tree | 89188fea0b3457421fe203cc7a2754523d0acf04 /src | |
| parent | core: Support session close with multicore. (diff) | |
| download | yuzu-9bf2a428f9e9359763be1bfd90c32371044c711e.tar.gz yuzu-9bf2a428f9e9359763be1bfd90c32371044c711e.tar.xz yuzu-9bf2a428f9e9359763be1bfd90c32371044c711e.zip | |
core: Add a configuration setting for use_multi_core.
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/core.cpp | 32 | ||||
| -rw-r--r-- | src/core/core.h | 10 | ||||
| -rw-r--r-- | src/core/core_cpu.cpp | 11 | ||||
| -rw-r--r-- | src/core/settings.h | 1 | ||||
| -rw-r--r-- | src/core/telemetry_session.cpp | 2 | ||||
| -rw-r--r-- | src/yuzu/configuration/config.cpp | 2 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_general.cpp | 3 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_general.ui | 7 | ||||
| -rw-r--r-- | src/yuzu_cmd/config.cpp | 1 | ||||
| -rw-r--r-- | src/yuzu_cmd/default_ini.h | 4 |
10 files changed, 56 insertions, 17 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp index 1e6be34c8..59c8940f7 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp | |||
| @@ -126,6 +126,21 @@ PerfStats::Results System::GetAndResetPerfStats() { | |||
| 126 | return perf_stats.GetAndResetStats(CoreTiming::GetGlobalTimeUs()); | 126 | return perf_stats.GetAndResetStats(CoreTiming::GetGlobalTimeUs()); |
| 127 | } | 127 | } |
| 128 | 128 | ||
| 129 | const std::shared_ptr<Kernel::Scheduler>& System::Scheduler(size_t core_index) { | ||
| 130 | if (!Settings::values.use_multi_core) { | ||
| 131 | // Always use Core 0 scheduler when multicore is disabled | ||
| 132 | return cpu_cores[0]->Scheduler(); | ||
| 133 | } | ||
| 134 | |||
| 135 | ASSERT(core_index < NUM_CPU_CORES); | ||
| 136 | return cpu_cores[core_index]->Scheduler(); | ||
| 137 | } | ||
| 138 | |||
| 139 | ARM_Interface& System::ArmInterface(size_t core_index) { | ||
| 140 | ASSERT(core_index < NUM_CPU_CORES); | ||
| 141 | return cpu_cores[core_index]->ArmInterface(); | ||
| 142 | } | ||
| 143 | |||
| 129 | System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) { | 144 | System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) { |
| 130 | NGLOG_DEBUG(HW_Memory, "initialized OK"); | 145 | NGLOG_DEBUG(HW_Memory, "initialized OK"); |
| 131 | 146 | ||
| @@ -154,9 +169,12 @@ System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) { | |||
| 154 | // Create threads for CPU cores 1-3, and build thread_to_cpu map | 169 | // Create threads for CPU cores 1-3, and build thread_to_cpu map |
| 155 | // CPU core 0 is run on the main thread | 170 | // CPU core 0 is run on the main thread |
| 156 | thread_to_cpu[std::this_thread::get_id()] = cpu_cores[0]; | 171 | thread_to_cpu[std::this_thread::get_id()] = cpu_cores[0]; |
| 157 | for (size_t index = 0; index < cpu_core_threads.size(); ++index) { | 172 | if (Settings::values.use_multi_core) { |
| 158 | cpu_core_threads[index] = std::make_unique<std::thread>(RunCpuCore, cpu_cores[index + 1]); | 173 | for (size_t index = 0; index < cpu_core_threads.size(); ++index) { |
| 159 | thread_to_cpu[cpu_core_threads[index]->get_id()] = cpu_cores[index + 1]; | 174 | cpu_core_threads[index] = |
| 175 | std::make_unique<std::thread>(RunCpuCore, cpu_cores[index + 1]); | ||
| 176 | thread_to_cpu[cpu_core_threads[index]->get_id()] = cpu_cores[index + 1]; | ||
| 177 | } | ||
| 160 | } | 178 | } |
| 161 | 179 | ||
| 162 | NGLOG_DEBUG(Core, "Initialized OK"); | 180 | NGLOG_DEBUG(Core, "Initialized OK"); |
| @@ -190,9 +208,11 @@ void System::Shutdown() { | |||
| 190 | 208 | ||
| 191 | // Close all CPU/threading state | 209 | // Close all CPU/threading state |
| 192 | cpu_barrier->NotifyEnd(); | 210 | cpu_barrier->NotifyEnd(); |
| 193 | for (auto& thread : cpu_core_threads) { | 211 | if (Settings::values.use_multi_core) { |
| 194 | thread->join(); | 212 | for (auto& thread : cpu_core_threads) { |
| 195 | thread.reset(); | 213 | thread->join(); |
| 214 | thread.reset(); | ||
| 215 | } | ||
| 196 | } | 216 | } |
| 197 | thread_to_cpu.clear(); | 217 | thread_to_cpu.clear(); |
| 198 | for (auto& cpu_core : cpu_cores) { | 218 | for (auto& cpu_core : cpu_cores) { |
diff --git a/src/core/core.h b/src/core/core.h index 561e7b48f..115061932 100644 --- a/src/core/core.h +++ b/src/core/core.h | |||
| @@ -112,10 +112,7 @@ public: | |||
| 112 | return CurrentCpuCore().ArmInterface(); | 112 | return CurrentCpuCore().ArmInterface(); |
| 113 | } | 113 | } |
| 114 | 114 | ||
| 115 | ARM_Interface& ArmInterface(size_t core_index) { | 115 | ARM_Interface& ArmInterface(size_t core_index); |
| 116 | ASSERT(core_index < NUM_CPU_CORES); | ||
| 117 | return cpu_cores[core_index]->ArmInterface(); | ||
| 118 | } | ||
| 119 | 116 | ||
| 120 | Tegra::GPU& GPU() { | 117 | Tegra::GPU& GPU() { |
| 121 | return *gpu_core; | 118 | return *gpu_core; |
| @@ -125,10 +122,7 @@ public: | |||
| 125 | return *CurrentCpuCore().Scheduler(); | 122 | return *CurrentCpuCore().Scheduler(); |
| 126 | } | 123 | } |
| 127 | 124 | ||
| 128 | const std::shared_ptr<Kernel::Scheduler>& Scheduler(size_t core_index) { | 125 | const std::shared_ptr<Kernel::Scheduler>& Scheduler(size_t core_index); |
| 129 | ASSERT(core_index < NUM_CPU_CORES); | ||
| 130 | return cpu_cores[core_index]->Scheduler(); | ||
| 131 | } | ||
| 132 | 126 | ||
| 133 | Kernel::SharedPtr<Kernel::Process>& CurrentProcess() { | 127 | Kernel::SharedPtr<Kernel::Process>& CurrentProcess() { |
| 134 | return current_process; | 128 | return current_process; |
diff --git a/src/core/core_cpu.cpp b/src/core/core_cpu.cpp index bd9869d28..099f2bb1a 100644 --- a/src/core/core_cpu.cpp +++ b/src/core/core_cpu.cpp | |||
| @@ -26,9 +26,12 @@ void CpuBarrier::NotifyEnd() { | |||
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | bool CpuBarrier::Rendezvous() { | 28 | bool CpuBarrier::Rendezvous() { |
| 29 | if (end) { | 29 | if (!Settings::values.use_multi_core) { |
| 30 | return false; | 30 | // Meaningless when running in single-core mode |
| 31 | } else { | 31 | return true; |
| 32 | } | ||
| 33 | |||
| 34 | if (!end) { | ||
| 32 | std::unique_lock<std::mutex> lock(mutex); | 35 | std::unique_lock<std::mutex> lock(mutex); |
| 33 | 36 | ||
| 34 | --cores_waiting; | 37 | --cores_waiting; |
| @@ -41,6 +44,8 @@ bool CpuBarrier::Rendezvous() { | |||
| 41 | condition.wait(lock); | 44 | condition.wait(lock); |
| 42 | return true; | 45 | return true; |
| 43 | } | 46 | } |
| 47 | |||
| 48 | return false; | ||
| 44 | } | 49 | } |
| 45 | 50 | ||
| 46 | Cpu::Cpu(std::shared_ptr<CpuBarrier> cpu_barrier, size_t core_index) | 51 | Cpu::Cpu(std::shared_ptr<CpuBarrier> cpu_barrier, size_t core_index) |
diff --git a/src/core/settings.h b/src/core/settings.h index cfec63c21..a7f1e5fa0 100644 --- a/src/core/settings.h +++ b/src/core/settings.h | |||
| @@ -121,6 +121,7 @@ struct Values { | |||
| 121 | 121 | ||
| 122 | // Core | 122 | // Core |
| 123 | bool use_cpu_jit; | 123 | bool use_cpu_jit; |
| 124 | bool use_multi_core; | ||
| 124 | 125 | ||
| 125 | // Data Storage | 126 | // Data Storage |
| 126 | bool use_virtual_sd; | 127 | bool use_virtual_sd; |
diff --git a/src/core/telemetry_session.cpp b/src/core/telemetry_session.cpp index 02c52bb55..a60aa1143 100644 --- a/src/core/telemetry_session.cpp +++ b/src/core/telemetry_session.cpp | |||
| @@ -155,6 +155,8 @@ TelemetrySession::TelemetrySession() { | |||
| 155 | 155 | ||
| 156 | // Log user configuration information | 156 | // Log user configuration information |
| 157 | AddField(Telemetry::FieldType::UserConfig, "Core_UseCpuJit", Settings::values.use_cpu_jit); | 157 | AddField(Telemetry::FieldType::UserConfig, "Core_UseCpuJit", Settings::values.use_cpu_jit); |
| 158 | AddField(Telemetry::FieldType::UserConfig, "Core_UseMultiCore", | ||
| 159 | Settings::values.use_multi_core); | ||
| 158 | AddField(Telemetry::FieldType::UserConfig, "Renderer_ResolutionFactor", | 160 | AddField(Telemetry::FieldType::UserConfig, "Renderer_ResolutionFactor", |
| 159 | Settings::values.resolution_factor); | 161 | Settings::values.resolution_factor); |
| 160 | AddField(Telemetry::FieldType::UserConfig, "Renderer_ToggleFramelimit", | 162 | AddField(Telemetry::FieldType::UserConfig, "Renderer_ToggleFramelimit", |
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index 8843f2078..8316db708 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp | |||
| @@ -78,6 +78,7 @@ void Config::ReadValues() { | |||
| 78 | 78 | ||
| 79 | qt_config->beginGroup("Core"); | 79 | qt_config->beginGroup("Core"); |
| 80 | Settings::values.use_cpu_jit = qt_config->value("use_cpu_jit", true).toBool(); | 80 | Settings::values.use_cpu_jit = qt_config->value("use_cpu_jit", true).toBool(); |
| 81 | Settings::values.use_multi_core = qt_config->value("use_multi_core", false).toBool(); | ||
| 81 | qt_config->endGroup(); | 82 | qt_config->endGroup(); |
| 82 | 83 | ||
| 83 | qt_config->beginGroup("Renderer"); | 84 | qt_config->beginGroup("Renderer"); |
| @@ -177,6 +178,7 @@ void Config::SaveValues() { | |||
| 177 | 178 | ||
| 178 | qt_config->beginGroup("Core"); | 179 | qt_config->beginGroup("Core"); |
| 179 | qt_config->setValue("use_cpu_jit", Settings::values.use_cpu_jit); | 180 | qt_config->setValue("use_cpu_jit", Settings::values.use_cpu_jit); |
| 181 | qt_config->setValue("use_multi_core", Settings::values.use_multi_core); | ||
| 180 | qt_config->endGroup(); | 182 | qt_config->endGroup(); |
| 181 | 183 | ||
| 182 | qt_config->beginGroup("Renderer"); | 184 | qt_config->beginGroup("Renderer"); |
diff --git a/src/yuzu/configuration/configure_general.cpp b/src/yuzu/configuration/configure_general.cpp index 2d73fc5aa..baa558667 100644 --- a/src/yuzu/configuration/configure_general.cpp +++ b/src/yuzu/configuration/configure_general.cpp | |||
| @@ -20,6 +20,7 @@ ConfigureGeneral::ConfigureGeneral(QWidget* parent) | |||
| 20 | this->setConfiguration(); | 20 | this->setConfiguration(); |
| 21 | 21 | ||
| 22 | ui->use_cpu_jit->setEnabled(!Core::System::GetInstance().IsPoweredOn()); | 22 | ui->use_cpu_jit->setEnabled(!Core::System::GetInstance().IsPoweredOn()); |
| 23 | ui->use_multi_core->setEnabled(!Core::System::GetInstance().IsPoweredOn()); | ||
| 23 | ui->use_docked_mode->setEnabled(!Core::System::GetInstance().IsPoweredOn()); | 24 | ui->use_docked_mode->setEnabled(!Core::System::GetInstance().IsPoweredOn()); |
| 24 | } | 25 | } |
| 25 | 26 | ||
| @@ -30,6 +31,7 @@ void ConfigureGeneral::setConfiguration() { | |||
| 30 | ui->toggle_check_exit->setChecked(UISettings::values.confirm_before_closing); | 31 | ui->toggle_check_exit->setChecked(UISettings::values.confirm_before_closing); |
| 31 | ui->theme_combobox->setCurrentIndex(ui->theme_combobox->findData(UISettings::values.theme)); | 32 | ui->theme_combobox->setCurrentIndex(ui->theme_combobox->findData(UISettings::values.theme)); |
| 32 | ui->use_cpu_jit->setChecked(Settings::values.use_cpu_jit); | 33 | ui->use_cpu_jit->setChecked(Settings::values.use_cpu_jit); |
| 34 | ui->use_multi_core->setChecked(Settings::values.use_multi_core); | ||
| 33 | ui->use_docked_mode->setChecked(Settings::values.use_docked_mode); | 35 | ui->use_docked_mode->setChecked(Settings::values.use_docked_mode); |
| 34 | } | 36 | } |
| 35 | 37 | ||
| @@ -40,6 +42,7 @@ void ConfigureGeneral::applyConfiguration() { | |||
| 40 | ui->theme_combobox->itemData(ui->theme_combobox->currentIndex()).toString(); | 42 | ui->theme_combobox->itemData(ui->theme_combobox->currentIndex()).toString(); |
| 41 | 43 | ||
| 42 | Settings::values.use_cpu_jit = ui->use_cpu_jit->isChecked(); | 44 | Settings::values.use_cpu_jit = ui->use_cpu_jit->isChecked(); |
| 45 | Settings::values.use_multi_core = ui->use_multi_core->isChecked(); | ||
| 43 | Settings::values.use_docked_mode = ui->use_docked_mode->isChecked(); | 46 | Settings::values.use_docked_mode = ui->use_docked_mode->isChecked(); |
| 44 | Settings::Apply(); | 47 | Settings::Apply(); |
| 45 | } | 48 | } |
diff --git a/src/yuzu/configuration/configure_general.ui b/src/yuzu/configuration/configure_general.ui index 1775c4d40..233adbe27 100644 --- a/src/yuzu/configuration/configure_general.ui +++ b/src/yuzu/configuration/configure_general.ui | |||
| @@ -58,6 +58,13 @@ | |||
| 58 | </property> | 58 | </property> |
| 59 | </widget> | 59 | </widget> |
| 60 | </item> | 60 | </item> |
| 61 | <item> | ||
| 62 | <widget class="QCheckBox" name="use_multi_core"> | ||
| 63 | <property name="text"> | ||
| 64 | <string>Enable multi-core</string> | ||
| 65 | </property> | ||
| 66 | </widget> | ||
| 67 | </item> | ||
| 61 | </layout> | 68 | </layout> |
| 62 | </item> | 69 | </item> |
| 63 | </layout> | 70 | </layout> |
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp index 675f9cafa..ee6e4d658 100644 --- a/src/yuzu_cmd/config.cpp +++ b/src/yuzu_cmd/config.cpp | |||
| @@ -91,6 +91,7 @@ void Config::ReadValues() { | |||
| 91 | 91 | ||
| 92 | // Core | 92 | // Core |
| 93 | Settings::values.use_cpu_jit = sdl2_config->GetBoolean("Core", "use_cpu_jit", true); | 93 | Settings::values.use_cpu_jit = sdl2_config->GetBoolean("Core", "use_cpu_jit", true); |
| 94 | Settings::values.use_multi_core = sdl2_config->GetBoolean("Core", "use_multi_core", false); | ||
| 94 | 95 | ||
| 95 | // Renderer | 96 | // Renderer |
| 96 | Settings::values.resolution_factor = | 97 | Settings::values.resolution_factor = |
diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h index 02254403d..1c438c3f5 100644 --- a/src/yuzu_cmd/default_ini.h +++ b/src/yuzu_cmd/default_ini.h | |||
| @@ -80,6 +80,10 @@ touch_device= | |||
| 80 | # 0: Interpreter (slow), 1 (default): JIT (fast) | 80 | # 0: Interpreter (slow), 1 (default): JIT (fast) |
| 81 | use_cpu_jit = | 81 | use_cpu_jit = |
| 82 | 82 | ||
| 83 | # Whether to use multi-core for CPU emulation | ||
| 84 | # 0 (default): Disabled, 1: Enabled | ||
| 85 | use_multi_core= | ||
| 86 | |||
| 83 | [Renderer] | 87 | [Renderer] |
| 84 | # Whether to use software or hardware rendering. | 88 | # Whether to use software or hardware rendering. |
| 85 | # 0: Software, 1 (default): Hardware | 89 | # 0: Software, 1 (default): Hardware |