【问题标题】:Interlocked operations with acquire and release semantic (multi-platform)具有获取和释放语义的联锁操作(多平台)
【发布时间】:2011-01-26 09:05:45
【问题描述】:

编辑: 好的,我有一个具体的问题。我想用获取和释放语义(伪代码)实现“交换”功能:

interlocked_inc_32(target)
{
    mov  ecx, 1
    lea  eax, target
    lock xadd, [eax], ecx
}

interlocked_inc_32_acq(target)
{
    lfence
    mov  ecx, 1
    lea  eax, target
    lock xadd, [eax], ecx
}

interlocked_inc_32_rel(target)
{
    sfence
    mov  ecx, 1
    lea  eax, target
    lock xadd, [eax], ecx
}

问题在于:我不知道如何实现它。我正在使用 Microsoft 的 Visual Studio 2010 在 Windows 下进行开发。当然,有“intrin.h”和“Windows.h”可以提供这些功能/内在函数。但是 InterlockedIncrementAcquire 只是 InterlockedIncrement 的定义,并提供了完整的内存屏障。这不是我所追求的。

/************ *************** ************* 原帖: /*************** *************** **********

我想写一个像 C++0x std::atomic 这样的原子类。 我只是想确定我的想法是否正确。

我想实现以下代码: 编辑(替换错误的实现)

enum memory_order { memory_order_acquire, memory_order_release, memory_order_acq_rel };

template<class T> class atomic;
template<class atomic_type, std::size_t = sizeof(typename ExtractType<atomic_type>::type)> struct interlocked;

template<template<class> class atomic_type> struct interlocked<atomic_type, 1>
{
    typedef typename ExtractType<atomic_type>::type bit8_type;

    void store(bit8_type value, memory_order order = memory_order_acq_rel) volatile {
        interlocked_xchg_8<order>(&static_cast<atomic_type volatile*>(this)->m_value, value);  
    }

    bit8_type load(memory_order order = memory_order_acq_rel) const volatile
    { 
        interlocked_cmp_xchg_8<order>(
            const_cast<bit8_type volatile*>(&static_cast<volatile const atomic_type *const>(this)->m_value), 
            static_cast<atomic_type const volatile*>(this)->m_value, 
            static_cast<atomic_type const volatile*>(this)->m_value
        ); 
    }

    bit8_type exhange(bit8_type, memory_order order = memory_order_acq_rel) volatile {
        return interlocked_xchg_8<order>(&static_cast<atomic_type volatile*>(this)->m_value, value);
    }

    bool compare_exchange(bit8_type comperand, bit8_type new_value, memory_order order = memory_order_acq_rel) volatile 
    {
        return interlocked_cmp_xchg_8<order>(
            &static_cast<atomic_type volatile*>(this)->m_value,
            new_value,
            comperand
        ) == comperand;

    }
};

template<template<class> class atomic_type> struct interlocked<atomic_type, 2> { };
template<template<class> class atomic_type> struct interlocked<atomic_type, 4> { };
template<template<class> class atomic_type> struct interlocked<atomic_type, 8> { };


template<class T>
class atomic : public interlocked<atomic<T>> { T m_value; };

有什么我遗漏的,或者这是一个“好”的非常好的实现。

感谢您的任何评论。最好的问候:

PS: 我不想为此提出一个新问题: 使用 boost::uint32_t(在 boost\cstdint.h 中)而不是 uint32_t(在 stdint.h 中)有什么好处?

【问题讨论】:

  • stdint.h 不是 C++ 标准的一部分。它是 C99 库。
  • SO 是一个获取特定问题的特定答案的网站。如果您有具体疑问,请专门询问。
  • @Space_C0wB0y:问题是:与 C++0x 实现相比,这个实现有什么缺点吗?
  • “我有什么遗漏的吗?”我不知道。你彻底测试了吗?如果没有,那么可能。
  • @FrEEzE2046:很多人写了很长的论文和博客文章来介绍atomic 的实现。这个问题的完整答案将跨越几页。对于这样的网站,这个问题只是不具体的。

标签: c++ portability atomic interlocked


【解决方案1】:

您的目标是 x86 硬件吗?它的缓存同步方案不是暗示你得到的是完整的内存屏障吗?您打算如何改进这一点?

【讨论】:

【解决方案2】:

您在这里面临的问题是锁定前缀意味着一个完整的内存屏障(mfence)。也就是说,因为在以前的 x86 处理器上没有不同类型的内存屏障和单独的 sfence/lfence 指令。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-31
    • 1970-01-01
    • 1970-01-01
    • 2011-06-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多