diff options
author | Philip Rebohle <philip.rebohle@tu-dortmund.de> | 2023-07-21 22:19:50 +0300 |
---|---|---|
committer | Philip Rebohle <philip.rebohle@tu-dortmund.de> | 2023-07-21 22:21:34 +0300 |
commit | f689ddd8386d52780ce050d2a0b8e78ac53ffb87 (patch) | |
tree | d1ae6d29f841ec7026f2fede3065918612236972 | |
parent | eed43c8524ec0003e0ffe8fe8cf7e524f02867bc (diff) |
[dxvk] Use dual queues for CS thread
Reduces lock contention since we can just swap out the entire queue
any time the worker thread runs out of stuff to do.
-rw-r--r-- | src/dxvk/dxvk_cs.cpp | 45 | ||||
-rw-r--r-- | src/dxvk/dxvk_cs.h | 2 |
2 files changed, 24 insertions, 23 deletions
diff --git a/src/dxvk/dxvk_cs.cpp b/src/dxvk/dxvk_cs.cpp index 7061f1a6..5f1b57df 100644 --- a/src/dxvk/dxvk_cs.cpp +++ b/src/dxvk/dxvk_cs.cpp @@ -119,7 +119,7 @@ namespace dxvk { { std::unique_lock<dxvk::mutex> lock(m_mutex); seq = ++m_chunksDispatched; - m_chunksQueued.push(std::move(chunk)); + m_chunksQueued.push_back(std::move(chunk)); } m_condOnAdd.notify_one(); @@ -152,35 +152,36 @@ namespace dxvk { void DxvkCsThread::threadFunc() { env::setThreadName("dxvk-cs"); - DxvkCsChunkRef chunk; + // Local chunk queue, we use two queues and swap between + // them in order to potentially reduce lock contention. + std::vector<DxvkCsChunkRef> chunks; try { while (!m_stopped.load()) { { std::unique_lock<dxvk::mutex> lock(m_mutex); - if (chunk) { - m_chunksExecuted++; - m_condOnSync.notify_one(); - - chunk = DxvkCsChunkRef(); - } - - if (m_chunksQueued.size() == 0) { - m_condOnAdd.wait(lock, [this] { - return (m_chunksQueued.size() != 0) - || (m_stopped.load()); - }); - } - - if (m_chunksQueued.size() != 0) { - chunk = std::move(m_chunksQueued.front()); - m_chunksQueued.pop(); - } + + m_condOnAdd.wait(lock, [this] { + return (!m_chunksQueued.empty()) + || (m_stopped.load()); + }); + + std::swap(chunks, m_chunksQueued); } - - if (chunk) { + + for (auto& chunk : chunks) { m_context->addStatCtr(DxvkStatCounter::CsChunkCount, 1); + chunk->executeAll(m_context.ptr()); + + m_chunksExecuted += 1; + m_condOnSync.notify_one(); + + // Explicitly free chunk here to release + // references to any resources held by it + chunk = DxvkCsChunkRef(); } + + chunks.clear(); } } catch (const DxvkError& e) { Logger::err("Exception on CS thread!"); diff --git a/src/dxvk/dxvk_cs.h b/src/dxvk/dxvk_cs.h index 72691c34..98bbc698 100644 --- a/src/dxvk/dxvk_cs.h +++ b/src/dxvk/dxvk_cs.h @@ -432,7 +432,7 @@ namespace dxvk { dxvk::mutex m_mutex; dxvk::condition_variable m_condOnAdd; dxvk::condition_variable m_condOnSync; - std::queue<DxvkCsChunkRef> m_chunksQueued; + std::vector<DxvkCsChunkRef> m_chunksQueued; dxvk::thread m_thread; void threadFunc(); |