在用户模式线程中旋转易失性变量是否安全?
我不太确定在用户模式线程中旋转易失性变量是否安全,以实现轻量级 spin_lock,我查看了 tbb 源代码,tbb_machine.h:170,
//! Spin WHILE the value of the variable is equal to a given value
/** T and U should be comparable types. */
template<typename T, typename U>
void spin_wait_while_eq( const volatile T& location, U value ) {
atomic_backoff backoff;
while( location==value ) backoff.pause();
}
并且atomic_backoff 中没有栅栏据我所见,班级。而从其他用户模式的 spin_lock 实现来看,大多数都使用 CAS(Compare and Swap)。
I'm not quite sure if it's safe to spin on a volatile variable in user-mode threads, to implement a light-weight spin_lock, I looked at the tbb source code, tbb_machine.h:170,
//! Spin WHILE the value of the variable is equal to a given value
/** T and U should be comparable types. */
template<typename T, typename U>
void spin_wait_while_eq( const volatile T& location, U value ) {
atomic_backoff backoff;
while( location==value ) backoff.pause();
}
And there is no fences in atomic_backoff class as I can see. While from other user-mode spin_lock implementation, most of them use CAS (Compare and Swap).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
棘手。我想说的是,理论上,这段代码并不安全。如果没有内存屏障,那么您所保护的数据访问可以跨自旋锁移动。然而,只有当编译器非常积极地内联并且可以在这种重新排序中看到目的时,才会这样做。
也许英特尔只是简单地确定此代码适用于所有当前的编译器,并且即使编译器理论上可以执行会破坏此代码的转换,但这些转换不会加速程序,因此编译器可能不会这么做。
另一种可能性是,此代码仅用于隐式实现
易失性
访问内存屏障的编译器。 Microsoft 的 Visual C++ 编译器(2005 及更高版本)执行此操作。您是否检查过它是否包装在#ifdef
块或类似的块中,仅在易失性
使用内存屏障的编译器上应用此实现?Tricky. I'd say that in theory, this code isn't safe. If there are no memory barriers then the data accesses you're guarding could be moved across the spinlock. However, this would only be done if the compiler inlined very aggressively, and could see a purpose in this reordering.
Perhaps Intel simply determined that this code works on all current compilers, and that even though a compiler could theoretically perform transformations that'd break this code, those transformations wouldn't speed up the program, and so compilers probably won't do it.
Another possibility is that this code is only used on compilers that implicitly implement memory barriers around
volatile
accesses. Microsoft's Visual C++ compiler (2005 and later) does this. Have you checked if this is wrapped in an#ifdef
block or similar, applying this implementation only on compilers wherevolatile
use memory barriers?请注意,这是一个自旋等待,而不是自旋锁定。不涉及写操作。什么都没有获得。
如果您尝试添加写入操作来完成锁定过程,则会出现无法解决的竞争。
Note that this is a spin wait and not a spin lock. There is no write operation involved. Nothing is acquired.
If you tried to add a write operation to complete the locking process, you would have an unsolvable race.