0
我想对tbb原子变量做bitTestAndSet
。bit tbb原子变量测试和设置(BTS)
atomic.h from tbb似乎没有任何位操作。
如果我将tbb原子变量当作正常指针处理,并且执行__sync_or_and_fetch
gcc编译器不允许这样做。
是否有解决方法?
相关问题:
assembly intrinsic for bit test and set (BTS)
我想对tbb原子变量做bitTestAndSet
。bit tbb原子变量测试和设置(BTS)
atomic.h from tbb似乎没有任何位操作。
如果我将tbb原子变量当作正常指针处理,并且执行__sync_or_and_fetch
gcc编译器不允许这样做。
是否有解决方法?
相关问题:
assembly intrinsic for bit test and set (BTS)
一个compare_and_swap回路可以使用,如:
// Atomically perform i|=j. Return previous value of i.
int bitTestAndSet(tbb::atomic<int>& 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;
}
注意,如果在第一次尝试时状态成功,将只有一个获得围栏,而不是一个完整的围栏。是否重要取决于上下文。
如果存在高争用风险,则应该在循环中使用某种退避方案。 TBB在内部为争用管理使用类atomic_backoff,但它目前不是公共TBB API的一部分。
还有第二种方法,如果可移植性不是问题,并且您愿意利用x86平台上tbb :: atomic和T的布局相同的无证事实。在这种情况下,只需使用汇编代码对tbb :: atomic进行操作即可。下面的程序演示了这种技术:
#include <tbb/tbb.h>
#include <cstdio>
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<int> 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);
}
}
感谢您的回答。我不希望位设置失败。如果我使用CAS,它可能无法设置该位。我想盲目设置位 – arunmoezhi
如果位集失败并重试,它有什么不同?这就好像线程稍后到达一样。并非所有的硬件都具有原子比特集。事实上,如果使用sync_or_and_fetch的结果,gcc会生成一个cmpxchg循环。我假设结果是有趣的,因为问题标题是“测试和设置”,而不仅仅是“设置”。 –
如果机器有硬件BTS指令,那么它会使用'cmpxchg'吗? – arunmoezhi