【发布时间】:2011-01-26 06:50:00
【问题描述】:
我编写了以下原子模板,以模仿即将在即将推出的 c++0x 标准中提供的原子操作。
但是,我不确定在返回基础值时进行的 __sync_synchronize() 调用是否必要。
据我了解,__sync_synchronize() 是一个完整的内存屏障,我不确定在返回对象值时是否需要如此昂贵的调用。
我很确定围绕值的设置需要它,但我也可以使用程序集来实现它..
__asm__ __volatile__ ( "rep;nop": : :"memory" );
有谁知道我在返回对象时肯定需要 synchronize()。
M.
template < typename T >
struct atomic
{
private:
volatile T obj;
public:
atomic( const T & t ) :
obj( t )
{
}
inline operator T()
{
__sync_synchronize(); // Not sure this is overkill
return obj;
}
inline atomic< T > & operator=( T val )
{
__sync_synchronize(); // Not sure if this is overkill
obj = val;
return *this;
}
inline T operator++()
{
return __sync_add_and_fetch( &obj, (T)1 );
}
inline T operator++( int )
{
return __sync_fetch_and_add( &obj, (T)1 );
}
inline T operator+=( T val )
{
return __sync_add_and_fetch( &obj, val );
}
inline T operator--()
{
return __sync_sub_and_fetch( &obj, (T)1 );
}
inline T operator--( int )
{
return __sync_fetch_and_sub( &obj, (T)1 );
}
inline T operator-=( T )
{
return __sync_sub_and_fetch( &obj, val );
}
// Perform an atomic CAS operation
// returning the value before the operation
inline T exchange( T oldVal, T newVal )
{
return __sync_val_compare_and_swap( &obj, oldval, newval );
}
};
更新:由于编译器优化,我想确保操作在面对读/写重新排序时保持一致。
【问题讨论】:
-
__sync_synchronize()来自哪里?该名称是为实现保留的,所以它是您的编译器的名称吗? -
@MSalters:它是一个完整的内存屏障内在,由 GCC 提供
-
@jalf。但是,它在我的 GCC (4.1.2) 版本中被破坏并产生无操作。我正在考虑通过 asm() 提供我自己的。 (x86 上的 sfence/lfence/mfence,solaris 上的???)。
-
仅供参考。 Solaris 对 sfence、lfence 和 mfence 分别使用“membar #LoadStore”、“membar #LoadLoad”和“membar #MemIssue”
标签: c++ templates c++11 atomic