1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-25 12:12:50 +01:00

SPU LLVM: Improve runtime SPU compilation preferences (#15250)

This commit is contained in:
Elad.Ash 2024-02-28 08:28:49 +02:00 committed by GitHub
parent 414a354511
commit 75ef154c12
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 59 additions and 4 deletions

View File

@ -379,8 +379,8 @@ public:
return m_head != 0;
}
template <typename... Args>
void push(Args&&... args)
template <bool Notify = true, typename... Args>
bool push(Args&&... args)
{
auto oldv = m_head.load();
auto item = new lf_queue_item<T>(load(oldv), std::forward<Args>(args)...);
@ -390,9 +390,19 @@ public:
item->m_link = load(oldv);
}
if (!oldv)
if (!oldv && Notify)
{
// Notify only if queue was empty
notify(true);
}
return !oldv;
}
void notify(bool force = false)
{
if (force || operator bool())
{
utils::bless<atomic_t<u32>>(&m_head)[1].notify_one();
}
}

View File

@ -4570,11 +4570,15 @@ struct spu_llvm
}
u32 worker_index = 0;
u32 notify_compile_count = 0;
std::vector<u8> notify_compile(worker_count);
m_workers = make_single<named_thread_group<spu_llvm_worker>>("SPUW.", worker_count);
auto workers_ptr = m_workers.load();
auto& workers = *workers_ptr;
usz add_count = 65535;
while (thread_ctrl::state() != thread_state::aborting)
{
for (const auto& pair : registered.pop_all())
@ -4590,9 +4594,24 @@ struct spu_llvm
if (enqueued.empty())
{
// Send pending notifications
if (notify_compile_count)
{
for (usz i = 0; i < worker_count; i++)
{
if (notify_compile[i])
{
(workers.begin() + (i % worker_count))->registered.notify();
}
}
}
// Interrupt profiler thread and put it to sleep
static_cast<void>(prof_mutex.reset());
thread_ctrl::wait_on(utils::bless<atomic_t<u32>>(&registered)[1], 0);
add_count = 65535; // Reset count
std::fill(notify_compile.begin(), notify_compile.end(), 0); // Reset notification flags
notify_compile_count = 0;
continue;
}
@ -4620,8 +4639,34 @@ struct spu_llvm
// Remove item from the queue
enqueued.erase(found_it);
// Prefer using an inactive thread
for (usz i = 0; i < worker_count && !!(workers.begin() + (worker_index % worker_count))->registered; i++)
{
worker_index++;
}
// Push the workload
(workers.begin() + (worker_index++ % worker_count))->registered.push(reinterpret_cast<u64>(_old), &func);
const bool notify = (workers.begin() + (worker_index % worker_count))->registered.template push<false>(reinterpret_cast<u64>(_old), &func);
if (notify && !notify_compile[worker_index % worker_count])
{
notify_compile[worker_index % worker_count] = 1;
notify_compile_count++;
if (notify_compile_count == notify_compile.size())
{
// Notify all
for (usz i = 0; i < worker_count; i++)
{
(workers.begin() + (i % worker_count))->registered.notify();
}
std::fill(notify_compile.begin(), notify_compile.end(), 0); // Reset notification flags
notify_compile_count = 0;
}
}
worker_index++;
}
static_cast<void>(prof_mutex.init_always([&]{ samples.clear(); }));