C++ 使用获取-释放语义原子地执行 if-not-equal-then-increment?

问题描述 投票:0回答:1

下面我有一些锁的实现。

如果

m_counter != -1
,则锁可用。如果此条件成立,则增加
m_counter

是否可以原子地/CAS 实现

!=
++
并使用获取-释放语义(而不是顺序一致)来提高性能?

#include <atomic>

struct Lock
{
    void take_lock()
    {
        while(true)
        {

////////////////////////////////////////////////////////////
//          Perform this commented-section atomically and using acquire-release semantics?

            if(-1 != m_counter)
            {
                ++m_counter;
////////////////////////////////////////////////////////////
                return;
            }

            while(-1 == m_counter.load(std::memory_order_relaxed))
            {

            }
        }
    }

    std::atomic<int8_t> m_counter{0};
};
c++ multithreading x86 atomic
1个回答
-1
投票

使用原子时,可以选择“无锁编程”。这看起来很简单,但有很多微妙的陷阱。例如,将

int8_t
std::atomic
一起使用是个坏主意,因为它可能会因多种原因而变慢(
int8_t
是自行播种的,这也大大增加了“错误共享”的危险)。

在您的情况下,这可能看起来像这样:

struct Lock
{
    void take_lock()
    {
        auto original = m_counter.load();
        int newValue;
        do {
            while(original == -1) {
                original = m_counter.load();
            }
            newValue = original + 1;
        } while (!m_counter.compare_exchange_strong(original, newValue));
    }

    std::atomic<int> m_counter{0};
};

https://godbolt.org/z/s5joW5Gzc

有关更多详细信息,请参阅 Herb Sutter 的 cppcon 演讲 “无锁编程(或杂耍剃刀刀片)”(请注意,标题表明需要掌握)(第二部分)。

© www.soinside.com 2019 - 2024. All rights reserved.