gpt4 book ai didi

c - 原子引用计数共享不可变数据是否需要内存屏障?

转载 作者:太空狗 更新时间:2023-10-29 16:40:50 24 4
gpt4 key购买 nike

我有一些不可变的数据结构,我想使用引用计数来管理它们,并在 SMP 系统上跨线程共享它们。

发布代码如下所示:

void avocado_release(struct avocado *p)
{
if (atomic_dec(p->refcount) == 0) {
free(p->pit);
free(p->juicy_innards);
free(p);
}
}

atomic_dec 是否需要内存屏障?如果是这样,什么样的内存屏障?

附加说明:该应用程序必须在 PowerPC 和 x86 上运行,因此欢迎提供任何特定于处理器的信息。我已经了解 GCC 原子内置函数。至于不变性,refcount 是唯一在对象持续时间内发生变化的字段。

最佳答案

在x86上,它会变成一个lock前缀的汇编指令,比如LOCK XADD
作为一条指令,它是不可中断的。作为添加的“功能”,lock 前缀会导致完整的内存屏障:

"...locked operations serialize all outstanding load and store operations (that is, wait for them to complete)." ..."Locked operations are atomic with respect to all other memory operations and all externally visible events. Only instruction fetch and page table accesses can pass locked instructions. Locked instructions can be used to synchronize data written by one processor and read by another processor." - Intel® 64 and IA-32 Architectures Software Developer’s Manual, Chapter 8.1.2.

内存屏障实际上是​​作为虚拟LOCK ORLOCK ANDthe .NET 中实现的。和 the JAVA JIT在 x86/x64 上,因为 mfence 在许多 CPU 上速度较慢,即使它保证可用,比如在 64 位模式下。 ( Does lock xchg have the same behavior as mfence? )
因此,无论您喜欢与否,您都可以在 x86 上拥有完整的围栏作为额外的好处。 :-)

在 PPC 上,情况有所不同。一个LL/SC对 - lwarx & stwcx - 内部有一个减法可用于将内存操作数加载到寄存器中,减去一个,然后如果没有其他存储到目标位置则将其写回,或者如果有则重试整个循环。 LL/SC 可以被中断(意味着它将失败并重试)。
也不代表自动全围栏。
然而,这不会以任何方式损害计数器的原子性。
这只是意味着在 x86 的情况下,您碰巧也“免费”获得了栅栏。
在 PPC 上,可以通过发出 (lw)sync 来插入(部分或)完整的栅栏instruction .

总而言之,原子计数器正常工作不需要显式内存屏障。

关于c - 原子引用计数共享不可变数据是否需要内存屏障?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2599238/

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