gpt4 book ai didi

c - 具有不 protected 并发修改的比较和交换行为

转载 作者:太空宇宙 更新时间:2023-11-04 04:42:25 24 4
gpt4 key购买 nike

假设某个线程正在某个内存位置上使用“同步值比较”和“交换”以原子方式设置值。另一个线程直接修改这个内存位置,而不进行比较和交换操作。在这种情况下(对于每个线程),一致性保证是什么.

最佳答案

具体行为将因体系结构而异。您没有指定要在哪个处理器上运行,并且无论__sync_val_compare_and_swap是作为处理器上的指令实现(如lock cmpxchg)还是通过LL/SC指令实现,都可能对观察到的行为产生影响(尽管我只打开LL/SC,因为它比CAS更敏感)。
此外,内存排序保证将改变行为:像ARM或电源之类的系统可能表现出不同于X86(-64)或SPARC的行为。我建议阅读Samy Al Bahra's ACM Queue article "Nonblocking Algorithms and Scalable Multicore Programming"以获取更多关于这如何影响程序行为的信息,不过我将对此稍作介绍。
你也没说你到底在做什么。只是任务吗?您是否正在用CAS循环实现一些无锁数据结构?现在还不清楚,一个更好的答案可以提供一个更好的问题。我将尽可能少地假设有什么值得讨论的,所以假设我们实际上在两个线程中都在做读-修改-写,并且我们正在尝试增加。如果我们有:

volatile uint32_t i = 0;
bool stop = false;

void *
t0(void *arg __attribute__((unused)))
{
volatile uint32_t snap;
while (!stop) {
snap = i;
__sync_val_compare_and_swap(&i, snap, snap + 1);
}
return NULL;
}

void *
t1(void *arg __attribute__((unused)))
{

while (!stop) {
i++;
}
return NULL
}

我们不能谈论一致性保证,因为没有任何东西是一致的。这个程序不一致。我们也不能说线程内的一致性保证,尽管很明显,有时 t0将无法增加值。
这个例子并不是那么无害。即使处理器内部增加了存储在内存中的一个数字(假设它不在缓存中),我们也不得不从内存中读取这个数字,增加这个数字,然后把这个数字写回去。我们的 t1将始终成功地递增一个值,但它有时只会是由 t0递增的值。
为什么?
增量是读/修改/写操作,就像CAS一样。 i++转换为 inc (%rax)并分解为从内存读取、递增、写入内存,或是否直接转换为这些指令,每个体系结构的内存读取和写入的时间和方式各不相同。
CAS和增量都有可能成功。运行 t0的内核可能还没有观察到 t1对内存的写操作,特别是在ARM或Power等宽松的内存顺序体系结构上。理论上这可能会导致 t0更新到 t1写入 i之后的值。
根据GCC文档, __sync_val_compare_and_swap意味着一个完整的内存屏障,但是另一个线程没有提供这样的屏障。
我们可以通过添加一个内存围栏来解决这个问题:
void *
t1(void *arg __attribute__((unused)))
{

while (!stop) {
i++;
__sync_synchronize();
}
return NULL
}

这很有帮助,因为我们现在保证了内存操作的总顺序,因为 __sync_synchronize设置了完整的内存屏障。我们仍然可以在 t0t1之间竞争,但是如果他们这样做了,我们将只失去其中一个增量,我们将永远不会像没有围栏的情况下那样“落后”。尽管如此,仍然没有一致性保证。现在可以保证的是,如果两个线程都运行,则至少会出现一个增量。
这是一致的还是正确的取决于您如何定义一致的或正确的。这当然比我们以前的“更正确”和“更一致”。
当然,如果我们想要真正的正确性,我们需要两个线程都使用 __sync_val_compare_and_swap。因为GCC插入了内存屏障,所以不管目标体系结构上的内存顺序语义如何,这实际上都保证了正确性。
最后,如果您正在编写此类代码,我建议您使用 Concurrency Kit。它的API更加令人愉快和全面,而且它并不意味着任何地方都存在内存障碍(当不需要时,这会对性能产生积极影响,当需要时会使代码更加明确,并且允许使用较轻的负载——或者在可能时只存储栅栏)。

关于c - 具有不 protected 并发修改的比较和交换行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24978038/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com