mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-13 19:29:14 +01:00
[util] Improve Spinlock implementation
Addresses two potential issues: - Our spinlocks are almost never contested, however the code generated is not ideal without the likely/unlikely hints. - In the unlike event that a spinlock is in fact contested, we'd yield immediately, even though most of the time we'd only have to wait for a few hundred cycles at most. Replacing our spinlocks with std::mutex is not an option due to much higher locking overhead in the uncontested case; doing so reduces performance significantly for the buffer slice and pipeline locks.
This commit is contained in:
parent
9541aef0b8
commit
8b9c03ce76
@ -13,7 +13,7 @@ namespace dxvk::sync {
|
||||
* in case the structure is not likely contested.
|
||||
*/
|
||||
class Spinlock {
|
||||
|
||||
constexpr static uint32_t SpinCount = 200;
|
||||
public:
|
||||
|
||||
Spinlock() { }
|
||||
@ -23,8 +23,14 @@ namespace dxvk::sync {
|
||||
Spinlock& operator = (const Spinlock&) = delete;
|
||||
|
||||
void lock() {
|
||||
while (!this->try_lock())
|
||||
while (unlikely(!try_lock())) {
|
||||
for (uint32_t i = 1; i < SpinCount; i++) {
|
||||
if (try_lock())
|
||||
return;
|
||||
}
|
||||
|
||||
dxvk::this_thread::yield();
|
||||
}
|
||||
}
|
||||
|
||||
void unlock() {
|
||||
@ -32,8 +38,8 @@ namespace dxvk::sync {
|
||||
}
|
||||
|
||||
bool try_lock() {
|
||||
return !m_lock.load()
|
||||
&& !m_lock.exchange(1, std::memory_order_acquire);
|
||||
return likely(!m_lock.load())
|
||||
&& likely(!m_lock.exchange(1, std::memory_order_acquire));
|
||||
}
|
||||
|
||||
private:
|
||||
|
Loading…
x
Reference in New Issue
Block a user