繁体   English   中英

设置一个位是否与同一个字上的其他位的并发组冲突?

[英]Does setting a bit collide with concurrent sets of other bits on the same word?

  1. 假设我有一个位图,并且几个线程(在多个CPU上运行)正在设置位。 没有使用同步,也没有原子操作。 此外,没有重置。 据我所知,当两个线程试图在同一个字上设置两个位时,最终只会有一个操作。 原因是对于要设置的位,应该读取和写回整个字,因此当两个读取同时完成时,当写回时,一个操作将覆盖另一个操作。 那是对的吗?

  2. 如果上述情况属实,那么字节操作也是如此吗? 也就是说,如果一个单词是2个字节,并且每个线程都试图将不同的字节设置为1,那么当它们同时完成时它们是否也会相互覆盖,或者某些系统是否支持将结果写回到单词的一部分?

询问的原因是试图弄清楚我必须放弃多少空间才能省略位/字节/字映射操作中的同步。

简而言之,它非常依赖于CPU和编译器。

假设您有一个包含零的32位值,并且线程A想要设置位0而线程B想要设置位1。

如您所述,这些是读取 - 修改 - 写入操作,同步问题是“如果它们发生冲突会发生什么”。

你需要避免的情况是这样的:

A: Reads (gets 0)
B: Reads (also gets zero)
A: Logical-OR bit 0, result = 1
A: Writes 1
B: Logical-OR bit 1, result = 2
B: Writes 2 - oops, should have been 3

......当正确的结果是......

A: Reads (gets 0)
A: Logical-OR bit 0, result = 1
A: Writes 1
B: Reads (gets 1)
B: Logical-OR bit 1, result = 2
B: Writes 3 - correct

在某些处理器上,读 - 修改写将是三个单独的指令,因此您将需要同步。 在其他方面,它将是一个单一的原子指令。 在多个Core / CPU系统上,它将是单个指令,但其他内核/ CPU可能能够访问,因此您将需要同步。

用字节做它可以是一样的。 在某些处理器内存架构中,您只能写入32位内存值,因此字节更新需要像以前一样进行读取 - 修改 - 写入。

更新X86架构(和Windows,特别是)

Windows在32位值上提供一组原子“Interlocked”操作,包括Logical OR 这些可以帮助您避免关键部分。 但要注意,因为Raymond Chen指出, 他们并没有解决所有问题 保持阅读该帖子,直到你明白它!

具体细节将取决于系统,并且可能依赖于编译器。 我想你可能不得不一直走到32位整数,然后才能摆脱你所担心的影响。

  1. 由于您指定的原因,我认为这是真的。

  2. 我看到它的方式,如果你的位图存储为char[] ,并且你的架构是字节可寻址的(它可以在内存中读取和写入单个字节,而不必读取整个单词),那么编译器可能生成原子操作。 即便如此,它仍然完全由实现定义,所以你不能依赖它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM