3

編集: わかりました、特定の質問があります。取得および解放セマンティック (疑似コード) を使用して「交換」機能を実装したい:

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 のようなアトミック クラスを作成したいと考えています。それについての私の考えが正しいかどうかを確認したいだけです。

次のコードを実装したいと思います: EDIT (悪い実装を置き換えました)

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: これについて新しい質問を開始したくありません: uint32_t (stdint.h 内) の代わりに boost::uint32_t (boost\cstdint.h 内) を使用する利点は何ですか?

4

2 に答える 2

3

x86ハードウェアをターゲットにしていますか?そのキャッシュ同期スキームは、完全なメモリバリアが得られることを意味しませんか?それをどのように改善しようとしていますか?

于 2011-02-02T22:45:41.990 に答える
2

ここで直面している問題は、ロック プレフィックスが完全なメモリ バリア (mfence) を意味することです。つまり、以前の x86 プロセッサでは、さまざまな種類のメモリ バリアや個別の sfence/lfence 命令が存在しなかったためです。

于 2011-04-18T14:00:57.767 に答える