Optimization 查找第一个位集并按原子方式取消设置它

Optimization 查找第一个位集并按原子方式取消设置它,optimization,locking,bit-manipulation,atomicity,Optimization,Locking,Bit Manipulation,Atomicity,我正在寻找以下代码行的指令(x86机器)或优化: lock() int x = ffs(words); // find first bit that set long words = unset(x, words); // unset the bit "x" in "words" unlock() 我不知道如何在没有锁定的情况下执行此操作。如果字是无符号类型,则可以按如下方式执行非原子计算: words &= ~-words; 或者,相当于 words &= words -

我正在寻找以下代码行的指令(x86机器)或优化:

lock()
int x = ffs(words); // find first bit that set
long words = unset(x, words); // unset the bit "x" in "words"
unlock()

我不知道如何在没有锁定的情况下执行此操作。

如果
是无符号类型,则可以按如下方式执行非原子计算:

words &= ~-words;
或者,相当于

words &= words - 1;
这是因为在
-words
中(假设2的补码,无符号类型必须使用),最低有效1和它右边的所有0都是不变的,而最低有效1左边的所有位都是反转的。因此,
单词&~-单词
将与
单词
相同,但最不显著的1除外


但是,为了实现原子化,您需要使用问题中指出的锁,或者需要围绕原子比较和交换进行自旋循环。

我怀疑您可以,除非有机器指令允许这种类型的操作。我担心您需要满足于比较和交换自旋循环。位域有多宽?二进制搜索至少会产生这样的循环O(log)。虽然你可能花在决策上的时间比理论上节省的时间多,特别是当你认为它不实用的时候。“第一”最重要还是最不重要?至少是按照<代码> FSH()/<代码>函数。目前我只需要64位或128位。我实际上也需要这个位,而不仅仅是取消设置它。如何知道设置了哪个位?而且这还需要锁。@w00d:你的意思是需要位,还是需要位的索引?位是
words&-words
,但要获得位的索引,需要使用类似
ffs
的内容。我知道它需要锁:我在最后一段说过。如果没有某种外部同步(锁、比较和交换或等效)是无法做到这一点的,它是位的索引。