在tbbprimefaces变量上进行位测试和设置(BTS)

我想在tbbprimefaces变量上做bitTestAndSet

来自tbb的atomic.h似乎没有任何位操作。

如果我将tbbprimefaces变量视为普通指针并执行__sync_or_and_fetch gcc编译器不允许这样做。

这有解决方法吗?

相关问题:

用于位测试和设置的组件(BTS)

可以使用compare_and_swap循环,如下所示:

 // Atomically perform i|=j. Return previous value of i. int bitTestAndSet( tbb::atomic& i, int j ) { int o = i; // Atomic read (o = "old value") while( (o|j)!=o ) { // Loop exits if another thread sets the bits int k = o; o = i.compare_and_swap(k|j,k); if( o==k ) break; // Successful swap } return o; } 

请注意,如果while条件在第一次尝试时成功,则只有获取栅栏,而不是完整栅栏。 这是否重要取决于背景。

如果存在高争用的风险,则应在循环中使用某种退避方案。 TBB在内部使用类atomic_backoff进行争用管理,但它目前不是公共TBB API的一部分。

还有第二种方法,如果可移植性不是问题,并且您愿意利用未记录的事实,即tbb :: atomic和T的布局在x86平台上是相同的。 在这种情况下,只需使用汇编代码对tbb :: atomic进行操作。 下面的程序演示了这种技术:

 #include  #include  inline int SetBit(int array[], int bit) { int x=1, y=0; asm("bts %2,%0\ncmovc %3,%1" : "+m" (*array), "+r"(y) : "r" (bit), "r"(x)); return y; } tbb::atomic Flags; volatile int Result; int main() { for( int i=0; i<16; ++i ) { int k = i*i%32; std::printf("bit at %2d was %d. Flags=%8x\n", k, SetBit((int*)&Flags,k), +Flags); } }