【问题标题】:Find first bit set and unset it atomically找到第一位设置并以原子方式取消设置
【发布时间】:2015-10-09 18:41:01
【问题描述】:

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

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

如果不加锁,我不知道该怎么做。

【问题讨论】:

  • 我怀疑你可以,除非有机器指令允许这种类型的操作。
  • 我担心您需要为此设置一个比较和交换自旋循环。位域有多宽?
  • 二分查找至少会产生这样的循环 O(log)。尽管您在决策上花费的时间可能比理论上节省的时间要多,尤其是当您认为展开不切实际时。
  • “第一”是最重要的还是最不重要的?
  • 这是最少的,根据ffs() 函数。我暂时只需要 64 位或 128 位。

标签: optimization locking bit-manipulation atomic


【解决方案1】:

如果words是无符号类型,那么非原子计算可以如下进行:

words &= ~-words;

或者,等价

words &= words - 1;

这是有效的,因为在-words 中(假设必须使用 2 的补码,无符号类型必须使用),最不重要的 1 和它右侧的所有 0 都没有改变,而最不重要的左侧的所有位显着 1 被反转。所以words & ~-words 将与words 相同,除了最不重要的 1。

但是,为了以原子方式执行此操作,您要么需要使用问题中指示的锁,要么需要围绕原子比较和交换执行自旋循环。

【讨论】:

  • 我实际上也需要这个位,而不仅仅是简单地取消它。我怎么知道设置了哪个位?而且这还需要锁。
  • @w00d:你的意思是你需要位,还是需要位的索引?该位是words & -words,但要获得该位的索引,您需要使用ffs 之类的东西。我知道它需要锁:我在上一段中说过。如果没有某种外部同步(锁定或比较和交换或等效),就无法做到这一点。
  • 这是位的索引。
猜你喜欢
  • 2019-06-06
  • 2022-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多