From 5566c5dff4d6430f704aeb66ca45615cb0df0176 Mon Sep 17 00:00:00 2001 From: Nicolas James Date: Wed, 8 Apr 2026 14:04:03 +1000 Subject: Reduce thread contention by introducing an atomic time point class - greatly reduces locking --- src/strategies/anti_lag/device_strategy.cc | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'src/strategies/anti_lag/device_strategy.cc') diff --git a/src/strategies/anti_lag/device_strategy.cc b/src/strategies/anti_lag/device_strategy.cc index 2d1d9ad..c0ab882 100644 --- a/src/strategies/anti_lag/device_strategy.cc +++ b/src/strategies/anti_lag/device_strategy.cc @@ -19,7 +19,7 @@ void AntiLagDeviceStrategy::notify_update(const VkAntiLagDataAMD& data) { this->is_enabled = !(data.mode == VK_ANTI_LAG_MODE_OFF_AMD); - this->delay = [&]() -> std::chrono::microseconds { + this->input_delay = [&]() -> std::chrono::microseconds { using namespace std::chrono; if (!data.maxFPS) { return 0us; @@ -40,7 +40,10 @@ void AntiLagDeviceStrategy::notify_update(const VkAntiLagDataAMD& data) { // If we're at the input stage, start marking submissions as relevant. this->frame_index.emplace(data.pPresentationInfo->frameIndex); + // Grab this before we unlock the mutex. + const auto delay = this->input_delay; lock.unlock(); + // We need to collect all queue submission and wait on them in this thread. // Input stage needs to wait for all queue submissions to complete. const auto queue_frame_spans = [&]() -> auto { @@ -61,25 +64,20 @@ void AntiLagDeviceStrategy::notify_update(const VkAntiLagDataAMD& data) { return queue_frame_spans; }(); - // Wait on them and relock the mutex. + // Wait on outstanding work to complete. for (const auto& frame_span : queue_frame_spans) { if (frame_span) { // Can still be null here. frame_span->await_completed(); } } - lock.lock(); - // We might need to wait a little more time to meet our frame limit. using namespace std::chrono; - if (this->delay != 0us && this->previous_input_release.has_value()) { - lock.unlock(); - std::this_thread::sleep_until(*this->previous_input_release + - this->delay); - lock.lock(); + if (delay != 0us && this->previous_input_release.has_value()) { + const auto last = this->previous_input_release.get(); + std::this_thread::sleep_until(last + delay); } - - this->previous_input_release = steady_clock::now(); + this->previous_input_release.set(steady_clock::now()); } bool AntiLagDeviceStrategy::should_track_submissions() { -- cgit v1.2.3