mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-29 00:33:01 +00: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
@ -1445,12 +1445,6 @@ extern void ppu_initialize(const ppu_module& info)
|
||||
// Compiler mutex (global)
|
||||
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
|
||||
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
|
||||
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())
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
|
||||
link_workload.emplace_back(obj_name, false);
|
||||
|
||||
// Check object file
|
||||
if (fs::is_file(cache_path + obj_name + ".gz") || fs::is_file(cache_path + obj_name))
|
||||
{
|
||||
if (!jit)
|
||||
{
|
||||
ppu_log.success("LLVM: Already exists: %s", obj_name);
|
||||
ppu_log.success("LLVM: Module exists: %s", obj_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
std::lock_guard lock(jmutex);
|
||||
jit->add(cache_path + obj_name);
|
||||
|
||||
ppu_log.success("LLVM: Loaded module %s", obj_name);
|
||||
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
|
||||
g_progr_ptotal++;
|
||||
}
|
||||
|
||||
// Create worker thread for compilation
|
||||
jthreads.emplace_back([&jit, obj_name = obj_name, part = std::move(part), &cache_path, jcores]()
|
||||
// Create worker threads for compilation (TODO: how many threads)
|
||||
{
|
||||
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
|
||||
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())
|
||||
{
|
||||
@ -1645,28 +1670,37 @@ extern void ppu_initialize(const ppu_module& info)
|
||||
// Use another JIT instance
|
||||
jit_compiler jit2({}, g_cfg.core.llvm_cpu, 0x1);
|
||||
ppu_initialize2(jit2, part, cache_path, obj_name);
|
||||
|
||||
ppu_log.success("LLVM: Compiled module %s", obj_name);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
ppu_log.success("LLVM: Compiled module %s", obj_name);
|
||||
});
|
||||
}
|
||||
|
||||
// Join worker threads
|
||||
for (auto& thread : jthreads)
|
||||
{
|
||||
thread.join();
|
||||
if (!is_compiled)
|
||||
{
|
||||
ppu_log.success("LLVM: Loaded module %s", obj_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Emu.IsStopped() || !get_current_cpu_thread())
|
||||
|
Loading…
x
Reference in New Issue
Block a user