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