From 9bf2a428f9e9359763be1bfd90c32371044c711e Mon Sep 17 00:00:00 2001 From: bunnei Date: Thu, 3 May 2018 00:34:54 -0400 Subject: [PATCH] core: Add a configuration setting for use_multi_core. --- src/core/core.cpp | 32 ++++++++++++++++---- src/core/core.h | 10 ++---- src/core/core_cpu.cpp | 11 +++++-- src/core/settings.h | 1 + src/core/telemetry_session.cpp | 2 ++ src/yuzu/configuration/config.cpp | 2 ++ src/yuzu/configuration/configure_general.cpp | 3 ++ src/yuzu/configuration/configure_general.ui | 7 +++++ src/yuzu_cmd/config.cpp | 1 + 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() { return perf_stats.GetAndResetStats(CoreTiming::GetGlobalTimeUs()); } +const std::shared_ptr& System::Scheduler(size_t core_index) { + if (!Settings::values.use_multi_core) { + // Always use Core 0 scheduler when multicore is disabled + return cpu_cores[0]->Scheduler(); + } + + ASSERT(core_index < NUM_CPU_CORES); + return cpu_cores[core_index]->Scheduler(); +} + +ARM_Interface& System::ArmInterface(size_t core_index) { + ASSERT(core_index < NUM_CPU_CORES); + return cpu_cores[core_index]->ArmInterface(); +} + System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) { NGLOG_DEBUG(HW_Memory, "initialized OK"); @@ -154,9 +169,12 @@ System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) { // Create threads for CPU cores 1-3, and build thread_to_cpu map // CPU core 0 is run on the main thread thread_to_cpu[std::this_thread::get_id()] = cpu_cores[0]; - for (size_t index = 0; index < cpu_core_threads.size(); ++index) { - cpu_core_threads[index] = std::make_unique(RunCpuCore, cpu_cores[index + 1]); - thread_to_cpu[cpu_core_threads[index]->get_id()] = cpu_cores[index + 1]; + if (Settings::values.use_multi_core) { + for (size_t index = 0; index < cpu_core_threads.size(); ++index) { + cpu_core_threads[index] = + std::make_unique(RunCpuCore, cpu_cores[index + 1]); + thread_to_cpu[cpu_core_threads[index]->get_id()] = cpu_cores[index + 1]; + } } NGLOG_DEBUG(Core, "Initialized OK"); @@ -190,9 +208,11 @@ void System::Shutdown() { // Close all CPU/threading state cpu_barrier->NotifyEnd(); - for (auto& thread : cpu_core_threads) { - thread->join(); - thread.reset(); + if (Settings::values.use_multi_core) { + for (auto& thread : cpu_core_threads) { + thread->join(); + thread.reset(); + } } thread_to_cpu.clear(); 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: return CurrentCpuCore().ArmInterface(); } - ARM_Interface& ArmInterface(size_t core_index) { - ASSERT(core_index < NUM_CPU_CORES); - return cpu_cores[core_index]->ArmInterface(); - } + ARM_Interface& ArmInterface(size_t core_index); Tegra::GPU& GPU() { return *gpu_core; @@ -125,10 +122,7 @@ public: return *CurrentCpuCore().Scheduler(); } - const std::shared_ptr& Scheduler(size_t core_index) { - ASSERT(core_index < NUM_CPU_CORES); - return cpu_cores[core_index]->Scheduler(); - } + const std::shared_ptr& Scheduler(size_t core_index); Kernel::SharedPtr& CurrentProcess() { 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() { } bool CpuBarrier::Rendezvous() { - if (end) { - return false; - } else { + if (!Settings::values.use_multi_core) { + // Meaningless when running in single-core mode + return true; + } + + if (!end) { std::unique_lock lock(mutex); --cores_waiting; @@ -41,6 +44,8 @@ bool CpuBarrier::Rendezvous() { condition.wait(lock); return true; } + + return false; } Cpu::Cpu(std::shared_ptr 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 { // Core bool use_cpu_jit; + bool use_multi_core; // Data Storage 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() { // Log user configuration information AddField(Telemetry::FieldType::UserConfig, "Core_UseCpuJit", Settings::values.use_cpu_jit); + AddField(Telemetry::FieldType::UserConfig, "Core_UseMultiCore", + Settings::values.use_multi_core); AddField(Telemetry::FieldType::UserConfig, "Renderer_ResolutionFactor", Settings::values.resolution_factor); 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() { qt_config->beginGroup("Core"); Settings::values.use_cpu_jit = qt_config->value("use_cpu_jit", true).toBool(); + Settings::values.use_multi_core = qt_config->value("use_multi_core", false).toBool(); qt_config->endGroup(); qt_config->beginGroup("Renderer"); @@ -177,6 +178,7 @@ void Config::SaveValues() { qt_config->beginGroup("Core"); qt_config->setValue("use_cpu_jit", Settings::values.use_cpu_jit); + qt_config->setValue("use_multi_core", Settings::values.use_multi_core); qt_config->endGroup(); 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) this->setConfiguration(); ui->use_cpu_jit->setEnabled(!Core::System::GetInstance().IsPoweredOn()); + ui->use_multi_core->setEnabled(!Core::System::GetInstance().IsPoweredOn()); ui->use_docked_mode->setEnabled(!Core::System::GetInstance().IsPoweredOn()); } @@ -30,6 +31,7 @@ void ConfigureGeneral::setConfiguration() { ui->toggle_check_exit->setChecked(UISettings::values.confirm_before_closing); ui->theme_combobox->setCurrentIndex(ui->theme_combobox->findData(UISettings::values.theme)); ui->use_cpu_jit->setChecked(Settings::values.use_cpu_jit); + ui->use_multi_core->setChecked(Settings::values.use_multi_core); ui->use_docked_mode->setChecked(Settings::values.use_docked_mode); } @@ -40,6 +42,7 @@ void ConfigureGeneral::applyConfiguration() { ui->theme_combobox->itemData(ui->theme_combobox->currentIndex()).toString(); Settings::values.use_cpu_jit = ui->use_cpu_jit->isChecked(); + Settings::values.use_multi_core = ui->use_multi_core->isChecked(); Settings::values.use_docked_mode = ui->use_docked_mode->isChecked(); Settings::Apply(); } 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 @@ + + + + Enable multi-core + + + 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() { // Core Settings::values.use_cpu_jit = sdl2_config->GetBoolean("Core", "use_cpu_jit", true); + Settings::values.use_multi_core = sdl2_config->GetBoolean("Core", "use_multi_core", false); // Renderer 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= # 0: Interpreter (slow), 1 (default): JIT (fast) use_cpu_jit = +# Whether to use multi-core for CPU emulation +# 0 (default): Disabled, 1: Enabled +use_multi_core= + [Renderer] # Whether to use software or hardware rendering. # 0: Software, 1 (default): Hardware