在第410页的Is Parallel Programming Hard, And, If So,What Can You Do About It中写道:
快速测验5.17:
为什么清单5.4中的
inc_count()
不需要使用原子指令?答案:
(..)在以下情况下需要原子指令: 每个线程的计数器变量小于全局global_count (..)
为简化起见,该句子适用于以下示例:
uint64 global_count = 0;
void f(){
uint32 sum = sum_of_smaller_thread_locals(); # sum is a variable
WRITE_ONCE(global_count, sum);
}
我不明白为什么在这种情况下我们需要原子指令?
答案 0 :(得分:1)
正如Peter Cordes指出的那样,每线程增量将需要原子指令。文字中给出了原因,但是多余的“但是”却使它有些模糊:
也就是说,在以下情况下需要原子指令 每个线程的计数器变量小于全局变量global_ 计数。
但是,请注意,在32位系统上,每线程计数器 变量可能需要限制为32位才能求和 准确,但使用64位global_count变量以避免溢出。 在这种情况下,必须将每个线程的计数器变量清零 定期进行以避免溢出。 请注意,此调零不能延迟太久或溢出 较小的每线程变量将导致。因此,这种方法 对基础系统施加实时要求,进而 必须格外小心地使用。相反,如果所有变量都是 大小相同,任何变量的溢出都是无害的,因为最终 总和将为单词大小的模数。
如果主线程清除每个线程的计数器,则需要通过原子交换来执行此操作,以避免可能的数据丢失。如果清除每个线程的增量,为避免数据丢失,它们将需要其他(可能更复杂)的互锁类型。