将非原子加载到与原子变量相同的缓存行会导致原子变量失败吗?
Will a non-atomic load to the same cache line as an atomic variable cause the atomic variable to fail?
在 ARMv8 CPU 上给出类似的东西(尽管这也可能适用于许多其他人):
class abcxzy
{
// Pragma align to cacheline to ensure they exist on same line.
unit32_t atomic_data;
uint32_t data;
void foo()
{
volatile asm (
" ldr w0, [address of data]\n"
"# Do stuff with data in w0..."
" str w0, [address of data]\n"
"1: ldaxr w0, [address of atomic_data]\n"
" add w1, w0, #0x1\n"
" stxr w2,w1, [address of atomic_data]\n"
" cbnz w2, 1b\n"
);
}
}
在 Asm 内联上设置适当的 clobbers 等,这样 C 和 Asm 就可以在彩虹小马和阳光的世界中快乐地共存。
在多个 CPU 的情况下,所有 运行 这段代码同时出现,存储到 data
会导致原子 load/store 到 atomic_data
失败?根据我的阅读,ARM 原子的东西在缓存行的基础上工作,但不清楚非原子存储是否会影响原子。我希望它不会(并假设它会......),但我正在寻找是否有其他人可以证实这一点。
好的,终于找到了我需要的东西,虽然我不喜欢它:
根据 ARM 文档,非独占存储到与独占存储相同的高速缓存行是否会导致独占存储失败是实现定义的。感谢 ARM。感谢精彩的非结论性信息。
编辑:
失败是指 stxr
命令没有写入内存并在状态寄存器中返回“1”。 "Your atomic data updated and needs new RMW"状态。
回答其他陈述:
是的,原子临界区应该越小越好。文档事件给出了多小的数字,它们确实非常合理。我希望我的部分永远不会超过 1k 或更多...
是的,在任何情况下您需要担心这种争用会导致性能下降或更糟,这意味着您的代码 "doing it wrong." ARM 文档以一种迂回的方式说明了这一点:)
至于将非原子加载和存储放在原子中 - 我上面的伪测试只是演示随机访问同一缓存行作为示例。在实际代码中,您显然应该避免这种情况。我只是想感受一下 "bad" 如果一个高速硬件计时器存储正在命中与锁相同的缓存行,那会是什么样子。再一次,不要这样做...
在 ARMv8 CPU 上给出类似的东西(尽管这也可能适用于许多其他人):
class abcxzy
{
// Pragma align to cacheline to ensure they exist on same line.
unit32_t atomic_data;
uint32_t data;
void foo()
{
volatile asm (
" ldr w0, [address of data]\n"
"# Do stuff with data in w0..."
" str w0, [address of data]\n"
"1: ldaxr w0, [address of atomic_data]\n"
" add w1, w0, #0x1\n"
" stxr w2,w1, [address of atomic_data]\n"
" cbnz w2, 1b\n"
);
}
}
在 Asm 内联上设置适当的 clobbers 等,这样 C 和 Asm 就可以在彩虹小马和阳光的世界中快乐地共存。
在多个 CPU 的情况下,所有 运行 这段代码同时出现,存储到 data
会导致原子 load/store 到 atomic_data
失败?根据我的阅读,ARM 原子的东西在缓存行的基础上工作,但不清楚非原子存储是否会影响原子。我希望它不会(并假设它会......),但我正在寻找是否有其他人可以证实这一点。
好的,终于找到了我需要的东西,虽然我不喜欢它:
根据 ARM 文档,非独占存储到与独占存储相同的高速缓存行是否会导致独占存储失败是实现定义的。感谢 ARM。感谢精彩的非结论性信息。
编辑:
失败是指 stxr
命令没有写入内存并在状态寄存器中返回“1”。 "Your atomic data updated and needs new RMW"状态。
回答其他陈述:
是的,原子临界区应该越小越好。文档事件给出了多小的数字,它们确实非常合理。我希望我的部分永远不会超过 1k 或更多...
是的,在任何情况下您需要担心这种争用会导致性能下降或更糟,这意味着您的代码 "doing it wrong." ARM 文档以一种迂回的方式说明了这一点:)
至于将非原子加载和存储放在原子中 - 我上面的伪测试只是演示随机访问同一缓存行作为示例。在实际代码中,您显然应该避免这种情况。我只是想感受一下 "bad" 如果一个高速硬件计时器存储正在命中与锁相同的缓存行,那会是什么样子。再一次,不要这样做...