Skip to content

Commit

Permalink
SPU LLVM: Improve runtime SPU compilation preferences
Browse files Browse the repository at this point in the history
  • Loading branch information
elad335 committed Feb 26, 2024
1 parent 3e83729 commit 32767ce
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 4 deletions.
14 changes: 12 additions & 2 deletions Utilities/lockless.h
Expand Up @@ -379,8 +379,8 @@ class lf_queue final
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)...);
Expand All @@ -393,6 +393,16 @@ class lf_queue final
if (!oldv)
{
// 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();
}
}
Expand Down
50 changes: 48 additions & 2 deletions rpcs3/Emu/Cell/SPUCommonRecompiler.cpp
Expand Up @@ -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())
Expand All @@ -4585,14 +4589,30 @@ struct spu_llvm
const auto lock = prof_mutex.init_always([&]{});

// Register new blocks to collect samples
samples.emplace(pair.first, 0);
// If the sample count is the same, prefer the last block that was pushed
samples.emplace(pair.first ? pair.first * 65536 + (add_count-- % 65536) : pair.first * 65536, 0);
}

if (enqueued.empty())
{
// Send pending notifications
if (notify_compile_count)
{
for (usz i = 0; i < worker_count; i++)
{
if (notify_compile[i])
{
(workers.begin() + (worker_index % 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;
}

Expand Down Expand Up @@ -4620,8 +4640,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_cout++;

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(); }));
Expand Down

0 comments on commit 32767ce

Please sign in to comment.