【发布时间】:2018-04-23 16:52:02
【问题描述】:
当我在 64 位项目的 VS2017 上分配 atomic_long 类型时,我一直在逐步完成所涉及的函数调用。我特别想看看当我将atomic_long 复制到一个非原子变量时会发生什么,以及它周围是否有任何锁定。
atomic_long ll = 10;
long t2 = ll;
最终以这个调用结束(我删除了一些 ifdefed out 的代码)
inline _Uint4_t _Load_seq_cst_4(volatile _Uint4_t *_Tgt)
{ /* load from *_Tgt atomically with
sequentially consistent memory order */
_Uint4_t _Value;
_Value = *_Tgt;
_Compiler_barrier();
return (_Value);
}
现在,我读到 from MSDN 说 32 位值的普通读取将是原子的:
对正确对齐的 32 位变量的简单读写是 原子操作。
...这就解释了为什么没有Interlocked 函数用于阅读;只有那些用于更改/比较的。我想知道_Compiler_barrier() 位在做什么。这是#defined
__MACHINE(void _ReadWriteBarrier(void))
...我又在MSDN 上发现了这个
限制可以重新排序内存访问的编译器优化 跨越通话点。
但我不明白,因为除了return 调用之外没有其他内存访问;肯定编译器不会将赋值移到下面吗?
有人可以澄清这个障碍的目的吗?
【问题讨论】:
-
也许它可以尝试
return (*_Tgt);。只是猜测。 -
你低估了优化器可以做什么。如果这不会改变程序的可观察行为,它肯定会被允许对内存访问进行重新排序,并且通常会这样做。从单线程的角度来看。屏障确保从另一个线程的角度来看禁止这样做。
标签: c++11 visual-c++ stdatomic