core: Add a configuration setting for use_multi_core.
This commit is contained in:
parent
cba69fdcd4
commit
9bf2a428f9
10 changed files with 56 additions and 17 deletions
|
@ -126,6 +126,21 @@ PerfStats::Results System::GetAndResetPerfStats() {
|
||||||
return perf_stats.GetAndResetStats(CoreTiming::GetGlobalTimeUs());
|
return perf_stats.GetAndResetStats(CoreTiming::GetGlobalTimeUs());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::shared_ptr<Kernel::Scheduler>& 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) {
|
System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) {
|
||||||
NGLOG_DEBUG(HW_Memory, "initialized OK");
|
NGLOG_DEBUG(HW_Memory, "initialized OK");
|
||||||
|
|
||||||
|
@ -154,10 +169,13 @@ System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) {
|
||||||
// Create threads for CPU cores 1-3, and build thread_to_cpu map
|
// Create threads for CPU cores 1-3, and build thread_to_cpu map
|
||||||
// CPU core 0 is run on the main thread
|
// CPU core 0 is run on the main thread
|
||||||
thread_to_cpu[std::this_thread::get_id()] = cpu_cores[0];
|
thread_to_cpu[std::this_thread::get_id()] = cpu_cores[0];
|
||||||
|
if (Settings::values.use_multi_core) {
|
||||||
for (size_t index = 0; index < cpu_core_threads.size(); ++index) {
|
for (size_t index = 0; index < cpu_core_threads.size(); ++index) {
|
||||||
cpu_core_threads[index] = std::make_unique<std::thread>(RunCpuCore, cpu_cores[index + 1]);
|
cpu_core_threads[index] =
|
||||||
|
std::make_unique<std::thread>(RunCpuCore, cpu_cores[index + 1]);
|
||||||
thread_to_cpu[cpu_core_threads[index]->get_id()] = cpu_cores[index + 1];
|
thread_to_cpu[cpu_core_threads[index]->get_id()] = cpu_cores[index + 1];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NGLOG_DEBUG(Core, "Initialized OK");
|
NGLOG_DEBUG(Core, "Initialized OK");
|
||||||
|
|
||||||
|
@ -190,10 +208,12 @@ void System::Shutdown() {
|
||||||
|
|
||||||
// Close all CPU/threading state
|
// Close all CPU/threading state
|
||||||
cpu_barrier->NotifyEnd();
|
cpu_barrier->NotifyEnd();
|
||||||
|
if (Settings::values.use_multi_core) {
|
||||||
for (auto& thread : cpu_core_threads) {
|
for (auto& thread : cpu_core_threads) {
|
||||||
thread->join();
|
thread->join();
|
||||||
thread.reset();
|
thread.reset();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
thread_to_cpu.clear();
|
thread_to_cpu.clear();
|
||||||
for (auto& cpu_core : cpu_cores) {
|
for (auto& cpu_core : cpu_cores) {
|
||||||
cpu_core.reset();
|
cpu_core.reset();
|
||||||
|
|
|
@ -112,10 +112,7 @@ public:
|
||||||
return CurrentCpuCore().ArmInterface();
|
return CurrentCpuCore().ArmInterface();
|
||||||
}
|
}
|
||||||
|
|
||||||
ARM_Interface& ArmInterface(size_t core_index) {
|
ARM_Interface& ArmInterface(size_t core_index);
|
||||||
ASSERT(core_index < NUM_CPU_CORES);
|
|
||||||
return cpu_cores[core_index]->ArmInterface();
|
|
||||||
}
|
|
||||||
|
|
||||||
Tegra::GPU& GPU() {
|
Tegra::GPU& GPU() {
|
||||||
return *gpu_core;
|
return *gpu_core;
|
||||||
|
@ -125,10 +122,7 @@ public:
|
||||||
return *CurrentCpuCore().Scheduler();
|
return *CurrentCpuCore().Scheduler();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::shared_ptr<Kernel::Scheduler>& Scheduler(size_t core_index) {
|
const std::shared_ptr<Kernel::Scheduler>& Scheduler(size_t core_index);
|
||||||
ASSERT(core_index < NUM_CPU_CORES);
|
|
||||||
return cpu_cores[core_index]->Scheduler();
|
|
||||||
}
|
|
||||||
|
|
||||||
Kernel::SharedPtr<Kernel::Process>& CurrentProcess() {
|
Kernel::SharedPtr<Kernel::Process>& CurrentProcess() {
|
||||||
return current_process;
|
return current_process;
|
||||||
|
|
|
@ -26,9 +26,12 @@ void CpuBarrier::NotifyEnd() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CpuBarrier::Rendezvous() {
|
bool CpuBarrier::Rendezvous() {
|
||||||
if (end) {
|
if (!Settings::values.use_multi_core) {
|
||||||
return false;
|
// Meaningless when running in single-core mode
|
||||||
} else {
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!end) {
|
||||||
std::unique_lock<std::mutex> lock(mutex);
|
std::unique_lock<std::mutex> lock(mutex);
|
||||||
|
|
||||||
--cores_waiting;
|
--cores_waiting;
|
||||||
|
@ -41,6 +44,8 @@ bool CpuBarrier::Rendezvous() {
|
||||||
condition.wait(lock);
|
condition.wait(lock);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Cpu::Cpu(std::shared_ptr<CpuBarrier> cpu_barrier, size_t core_index)
|
Cpu::Cpu(std::shared_ptr<CpuBarrier> cpu_barrier, size_t core_index)
|
||||||
|
|
|
@ -121,6 +121,7 @@ struct Values {
|
||||||
|
|
||||||
// Core
|
// Core
|
||||||
bool use_cpu_jit;
|
bool use_cpu_jit;
|
||||||
|
bool use_multi_core;
|
||||||
|
|
||||||
// Data Storage
|
// Data Storage
|
||||||
bool use_virtual_sd;
|
bool use_virtual_sd;
|
||||||
|
|
|
@ -155,6 +155,8 @@ TelemetrySession::TelemetrySession() {
|
||||||
|
|
||||||
// Log user configuration information
|
// Log user configuration information
|
||||||
AddField(Telemetry::FieldType::UserConfig, "Core_UseCpuJit", Settings::values.use_cpu_jit);
|
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",
|
AddField(Telemetry::FieldType::UserConfig, "Renderer_ResolutionFactor",
|
||||||
Settings::values.resolution_factor);
|
Settings::values.resolution_factor);
|
||||||
AddField(Telemetry::FieldType::UserConfig, "Renderer_ToggleFramelimit",
|
AddField(Telemetry::FieldType::UserConfig, "Renderer_ToggleFramelimit",
|
||||||
|
|
|
@ -78,6 +78,7 @@ void Config::ReadValues() {
|
||||||
|
|
||||||
qt_config->beginGroup("Core");
|
qt_config->beginGroup("Core");
|
||||||
Settings::values.use_cpu_jit = qt_config->value("use_cpu_jit", true).toBool();
|
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->endGroup();
|
||||||
|
|
||||||
qt_config->beginGroup("Renderer");
|
qt_config->beginGroup("Renderer");
|
||||||
|
@ -177,6 +178,7 @@ void Config::SaveValues() {
|
||||||
|
|
||||||
qt_config->beginGroup("Core");
|
qt_config->beginGroup("Core");
|
||||||
qt_config->setValue("use_cpu_jit", Settings::values.use_cpu_jit);
|
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->endGroup();
|
||||||
|
|
||||||
qt_config->beginGroup("Renderer");
|
qt_config->beginGroup("Renderer");
|
||||||
|
|
|
@ -20,6 +20,7 @@ ConfigureGeneral::ConfigureGeneral(QWidget* parent)
|
||||||
this->setConfiguration();
|
this->setConfiguration();
|
||||||
|
|
||||||
ui->use_cpu_jit->setEnabled(!Core::System::GetInstance().IsPoweredOn());
|
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());
|
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->toggle_check_exit->setChecked(UISettings::values.confirm_before_closing);
|
||||||
ui->theme_combobox->setCurrentIndex(ui->theme_combobox->findData(UISettings::values.theme));
|
ui->theme_combobox->setCurrentIndex(ui->theme_combobox->findData(UISettings::values.theme));
|
||||||
ui->use_cpu_jit->setChecked(Settings::values.use_cpu_jit);
|
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);
|
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();
|
ui->theme_combobox->itemData(ui->theme_combobox->currentIndex()).toString();
|
||||||
|
|
||||||
Settings::values.use_cpu_jit = ui->use_cpu_jit->isChecked();
|
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::values.use_docked_mode = ui->use_docked_mode->isChecked();
|
||||||
Settings::Apply();
|
Settings::Apply();
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,13 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="use_multi_core">
|
||||||
|
<property name="text">
|
||||||
|
<string>Enable multi-core</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|
|
@ -91,6 +91,7 @@ void Config::ReadValues() {
|
||||||
|
|
||||||
// Core
|
// Core
|
||||||
Settings::values.use_cpu_jit = sdl2_config->GetBoolean("Core", "use_cpu_jit", true);
|
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
|
// Renderer
|
||||||
Settings::values.resolution_factor =
|
Settings::values.resolution_factor =
|
||||||
|
|
|
@ -80,6 +80,10 @@ touch_device=
|
||||||
# 0: Interpreter (slow), 1 (default): JIT (fast)
|
# 0: Interpreter (slow), 1 (default): JIT (fast)
|
||||||
use_cpu_jit =
|
use_cpu_jit =
|
||||||
|
|
||||||
|
# Whether to use multi-core for CPU emulation
|
||||||
|
# 0 (default): Disabled, 1: Enabled
|
||||||
|
use_multi_core=
|
||||||
|
|
||||||
[Renderer]
|
[Renderer]
|
||||||
# Whether to use software or hardware rendering.
|
# Whether to use software or hardware rendering.
|
||||||
# 0: Software, 1 (default): Hardware
|
# 0: Software, 1 (default): Hardware
|
||||||
|
|
Loading…
Reference in a new issue