Merge pull request #2893 from SChernykh/dev

KawPow OpenCL: use separate UV loop for building programs
This commit is contained in:
xmrig 2022-01-24 19:30:24 +07:00 committed by GitHub
commit faa7095865
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -153,9 +153,35 @@ static KawPowCache cache;
#define mix_dst() ("mix[" + std::to_string(mix_seq_dst[(mix_seq_dst_cnt++) % KPHash::REGS]) + "]") #define mix_dst() ("mix[" + std::to_string(mix_seq_dst[(mix_seq_dst_cnt++) % KPHash::REGS]) + "]")
#define mix_cache() ("mix[" + std::to_string(mix_seq_cache[(mix_seq_cache_cnt++) % KPHash::REGS]) + "]") #define mix_cache() ("mix[" + std::to_string(mix_seq_cache[(mix_seq_cache_cnt++) % KPHash::REGS]) + "]")
class KawPowBaton : public Baton<uv_work_t>
{
public:
inline KawPowBaton(const IOclRunner& runner, uint64_t period, uint32_t worksize) :
runner(runner),
period(period),
worksize(worksize)
{}
const IOclRunner& runner;
const uint64_t period;
const uint32_t worksize;
};
class KawPowBuilder class KawPowBuilder
{ {
public: public:
~KawPowBuilder()
{
if (m_loop) {
uv_async_send(&m_shutdownAsync);
uv_thread_join(&m_loopThread);
delete m_loop;
}
}
void build_async(const IOclRunner& runner, uint64_t period, uint32_t worksize);
cl_kernel build(const IOclRunner &runner, uint64_t period, uint32_t worksize) cl_kernel build(const IOclRunner &runner, uint64_t period, uint32_t worksize)
{ {
std::lock_guard<std::mutex> lock(m_mutex); std::lock_guard<std::mutex> lock(m_mutex);
@ -368,40 +394,54 @@ private:
st.jcong = 69069 * st.jcong + 1234567; st.jcong = 69069 * st.jcong + 1234567;
return ((MWC ^ st.jcong) + st.jsr); return ((MWC ^ st.jcong) + st.jsr);
} }
};
private:
uv_loop_t* m_loop = nullptr;
uv_thread_t m_loopThread = {};
uv_async_t m_shutdownAsync = {};
class KawPowBaton : public Baton<uv_work_t> static void loop(void* data)
{ {
public: KawPowBuilder* builder = static_cast<KawPowBuilder*>(data);
inline KawPowBaton(const IOclRunner &runner, uint64_t period, uint32_t worksize) : uv_run(builder->m_loop, UV_RUN_DEFAULT);
runner(runner), uv_loop_close(builder->m_loop);
period(period), }
worksize(worksize)
{}
const IOclRunner &runner;
const uint64_t period;
const uint32_t worksize;
}; };
static KawPowBuilder builder; static KawPowBuilder builder;
void KawPowBuilder::build_async(const IOclRunner& runner, uint64_t period, uint32_t worksize)
{
std::lock_guard<std::mutex> lock(m_mutex);
if (!m_loop) {
m_loop = new uv_loop_t{};
uv_loop_init(m_loop);
uv_async_init(m_loop, &m_shutdownAsync, [](uv_async_t* handle) { uv_close(reinterpret_cast<uv_handle_t*>(handle), nullptr); });
uv_thread_create(&m_loopThread, loop, this);
}
KawPowBaton* baton = new KawPowBaton(runner, period, worksize);
uv_queue_work(m_loop, &baton->req,
[](uv_work_t* req) {
KawPowBaton* baton = static_cast<KawPowBaton*>(req->data);
builder.build(baton->runner, baton->period, baton->worksize);
},
[](uv_work_t* req, int) { delete static_cast<KawPowBaton*>(req->data); }
);
}
cl_kernel OclKawPow::get(const IOclRunner &runner, uint64_t height, uint32_t worksize) cl_kernel OclKawPow::get(const IOclRunner &runner, uint64_t height, uint32_t worksize)
{ {
const uint64_t period = height / KPHash::PERIOD_LENGTH; const uint64_t period = height / KPHash::PERIOD_LENGTH;
KawPowBaton* baton = new KawPowBaton(runner, period + 1, worksize); if (!cache.search(runner, period + 1, worksize)) {
builder.build_async(runner, period + 1, worksize);
uv_queue_work(uv_default_loop(), &baton->req, }
[](uv_work_t *req) {
KawPowBaton* baton = static_cast<KawPowBaton*>(req->data);
builder.build(baton->runner, baton->period, baton->worksize);
},
[](uv_work_t *req, int) { delete static_cast<KawPowBaton*>(req->data); }
);
cl_kernel kernel = cache.search(runner, period, worksize); cl_kernel kernel = cache.search(runner, period, worksize);
if (kernel) { if (kernel) {