在TBB原子变量位测试和设置(BTS) [英] bit test and set (BTS) on a tbb atomic variable

查看:280
本文介绍了在TBB原子变量位测试和设置(BTS)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要做的 bitTestAndSet 在TBB原子变量。

I want to do bitTestAndSet on a tbb atomic variable.

atomic.h中从TBB 似乎并不具备任何位操作。

atomic.h from tbb does not seem to have any bit operations.

如果我对待TBB原子变量作为一个正常的指针,并做 __ sync_or_and_fetch gcc编译器不允许。

If I treat the tbb atomic variable as a normal pointer and do __sync_or_and_fetch gcc compiler doesn't allow that.

有没有解决方法呢?

相关问题:

<一个href=\"http://stackoverflow.com/questions/22974382/assembly-intrinsic-for-bit-test-and-set-bts\">assembly内在的位测试和设置(BTS)

推荐答案

一个compare_and_swap循环可以使用,这样的:

A compare_and_swap loop can be used, like this:

// 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;
}

请注意,如果在第一次尝试while条件成功,将有只获取栅栏,不是一个完整的围墙。无论是重要的取决于上下文。

Note that if the while condition succeeds on the first try, there will be only an acquire fence, not a full fence. Whether that matters depends on context.

如果有高争的危险,那么某种形式的补偿方案应该是在循环使用。 TBB使用争管理类atomic_backoff内部,但它不是目前大众TBB API的一部分。

If there is risk of high contention, then some sort of backoff scheme should be be used in the loop. TBB uses a class atomic_backoff for contention management internally, but it's not currently part of the public TBB API.

还有第二个办法,如果便携性是不是一个问题,你是愿意利用未公开的事实,TBB ::原子和T的布局是在x86平台上是相同的。在这种情况下,只是在操作TBB原子::使用汇编code。下面的程序演示了这种方法:

There is a second way, if portability is not a concern and you are willing to exploit the undocumented fact that the layout of a tbb::atomic and T are the same on x86 platforms. In that case, just operate on the tbb::atomic using assembly code. The program below demonstrates this technique:

#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);
    }
}

这篇关于在TBB原子变量位测试和设置(BTS)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆