mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-09 00:11:24 +12:00
PPU: use named_thread_group to compile modules
Improves internal logic by not using too many threads.
This commit is contained in:
parent
8d847d6f1c
commit
bdbc7b5f1d
1 changed files with 61 additions and 27 deletions
|
@ -1445,12 +1445,6 @@ extern void ppu_initialize(const ppu_module& info)
|
||||||
// Compiler mutex (global)
|
// Compiler mutex (global)
|
||||||
static shared_mutex jmutex;
|
static shared_mutex jmutex;
|
||||||
|
|
||||||
// Get jit core allocator instance
|
|
||||||
const auto jcores = g_fxo->get<jit_core_allocator>();
|
|
||||||
|
|
||||||
// Worker threads
|
|
||||||
std::vector<std::thread> jthreads;
|
|
||||||
|
|
||||||
// Global variables to initialize
|
// Global variables to initialize
|
||||||
std::vector<std::pair<std::string, u64>> globals;
|
std::vector<std::pair<std::string, u64>> globals;
|
||||||
|
|
||||||
|
@ -1460,6 +1454,15 @@ extern void ppu_initialize(const ppu_module& info)
|
||||||
// Difference between function name and current location
|
// Difference between function name and current location
|
||||||
const u32 reloc = info.name.empty() ? 0 : info.segs.at(0).addr;
|
const u32 reloc = info.name.empty() ? 0 : info.segs.at(0).addr;
|
||||||
|
|
||||||
|
// Info sent to threads
|
||||||
|
std::vector<std::pair<std::string, ppu_module>> workload;
|
||||||
|
|
||||||
|
// Info to load to main JIT instance (true - compiled)
|
||||||
|
std::vector<std::pair<std::string, bool>> link_workload;
|
||||||
|
|
||||||
|
// Sync variable to acquire workloads
|
||||||
|
atomic_t<u32> work_cv = 0;
|
||||||
|
|
||||||
while (jit_mod.vars.empty() && fpos < info.funcs.size())
|
while (jit_mod.vars.empty() && fpos < info.funcs.size())
|
||||||
{
|
{
|
||||||
// Initialize compiler instance
|
// Initialize compiler instance
|
||||||
|
@ -1609,34 +1612,56 @@ extern void ppu_initialize(const ppu_module& info)
|
||||||
globals.emplace_back(fmt::format("__seg%u_%x", i, suffix), info.segs[i].addr);
|
globals.emplace_back(fmt::format("__seg%u_%x", i, suffix), info.segs[i].addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
link_workload.emplace_back(obj_name, false);
|
||||||
|
|
||||||
// Check object file
|
// Check object file
|
||||||
if (fs::is_file(cache_path + obj_name + ".gz") || fs::is_file(cache_path + obj_name))
|
if (fs::is_file(cache_path + obj_name + ".gz") || fs::is_file(cache_path + obj_name))
|
||||||
{
|
{
|
||||||
if (!jit)
|
if (!jit)
|
||||||
{
|
{
|
||||||
ppu_log.success("LLVM: Already exists: %s", obj_name);
|
ppu_log.success("LLVM: Module exists: %s", obj_name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard lock(jmutex);
|
|
||||||
jit->add(cache_path + obj_name);
|
|
||||||
|
|
||||||
ppu_log.success("LLVM: Loaded module %s", obj_name);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Adjust information (is_compiled)
|
||||||
|
link_workload.back().second = true;
|
||||||
|
|
||||||
|
// Fill workload list for compilation
|
||||||
|
workload.emplace_back(std::move(obj_name), std::move(part));
|
||||||
|
|
||||||
// Update progress dialog
|
// Update progress dialog
|
||||||
g_progr_ptotal++;
|
g_progr_ptotal++;
|
||||||
|
}
|
||||||
|
|
||||||
// Create worker thread for compilation
|
// Create worker threads for compilation (TODO: how many threads)
|
||||||
jthreads.emplace_back([&jit, obj_name = obj_name, part = std::move(part), &cache_path, jcores]()
|
{
|
||||||
|
u32 thread_count = Emu.GetMaxThreads();
|
||||||
|
|
||||||
|
if (workload.size() < thread_count)
|
||||||
|
{
|
||||||
|
thread_count = ::size32(workload);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct thread_index_allocator
|
||||||
|
{
|
||||||
|
atomic_t<u64> index = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
named_thread_group threads(fmt::format("PPUW.%u.", ++g_fxo->get<thread_index_allocator>()->index), thread_count, [&]()
|
||||||
{
|
{
|
||||||
// Set low priority
|
// Set low priority
|
||||||
thread_ctrl::set_native_priority(-1);
|
thread_ctrl::set_native_priority(-1);
|
||||||
|
|
||||||
// Allocate "core"
|
for (u32 i = work_cv++; i < workload.size(); i = work_cv++)
|
||||||
{
|
{
|
||||||
std::lock_guard jlock(jcores->sem);
|
// Keep allocating workload
|
||||||
|
const auto [obj_name, part] = std::as_const(workload)[i];
|
||||||
|
|
||||||
|
// Allocate "core"
|
||||||
|
std::lock_guard jlock(g_fxo->get<jit_core_allocator>()->sem);
|
||||||
|
|
||||||
if (!Emu.IsStopped())
|
if (!Emu.IsStopped())
|
||||||
{
|
{
|
||||||
|
@ -1645,28 +1670,37 @@ extern void ppu_initialize(const ppu_module& info)
|
||||||
// Use another JIT instance
|
// Use another JIT instance
|
||||||
jit_compiler jit2({}, g_cfg.core.llvm_cpu, 0x1);
|
jit_compiler jit2({}, g_cfg.core.llvm_cpu, 0x1);
|
||||||
ppu_initialize2(jit2, part, cache_path, obj_name);
|
ppu_initialize2(jit2, part, cache_path, obj_name);
|
||||||
|
|
||||||
|
ppu_log.success("LLVM: Compiled module %s", obj_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_progr_pdone++;
|
g_progr_pdone++;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (Emu.IsStopped() || !jit || !fs::is_file(cache_path + obj_name + ".gz"))
|
threads.join();
|
||||||
|
|
||||||
|
if (Emu.IsStopped() || !get_current_cpu_thread())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::lock_guard lock(jmutex);
|
||||||
|
|
||||||
|
for (auto [obj_name, is_compiled] : link_workload)
|
||||||
|
{
|
||||||
|
if (Emu.IsStopped())
|
||||||
{
|
{
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Proceed with original JIT instance
|
|
||||||
std::lock_guard lock(jmutex);
|
|
||||||
jit->add(cache_path + obj_name);
|
jit->add(cache_path + obj_name);
|
||||||
|
|
||||||
ppu_log.success("LLVM: Compiled module %s", obj_name);
|
if (!is_compiled)
|
||||||
});
|
{
|
||||||
}
|
ppu_log.success("LLVM: Loaded module %s", obj_name);
|
||||||
|
}
|
||||||
// Join worker threads
|
}
|
||||||
for (auto& thread : jthreads)
|
|
||||||
{
|
|
||||||
thread.join();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Emu.IsStopped() || !get_current_cpu_thread())
|
if (Emu.IsStopped() || !get_current_cpu_thread())
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue