_ReadWriteBarrier 如何向上传播调用树?
Posted
技术标签:
【中文标题】_ReadWriteBarrier 如何向上传播调用树?【英文标题】:How does _ReadWriteBarrier propagate up the call tree? 【发布时间】:2010-01-28 17:19:12 【问题描述】:我正在查看 documentation 中的这段文字,用于 Visual C++ 的 _ReadWriteBarrier 内在函数:
在过去的 Visual C++ 版本中 编译器,_ReadWriteBarrier 和 _WriteBarrier 函数仅在本地强制执行,不影响 函数调用树。在视觉 C++ 2005 及更高版本,这些函数 一直强制执行 树。
我了解障碍在函数中的作用,但“调用树向上”似乎暗示函数foo()
调用函数bar()
可以知道bar()
是否包含障碍。在 VC2005 中实际改变了什么来实现这一点...调用约定/ABI,编译器完成的一些全局分析,还是什么?
【问题讨论】:
【参考方案1】:MS 文档从来都不是很好,这个就是一个很好的例子。 _ReadWriteBarrier 有 2 个部分:
-
告诉 CPU 做一个内存屏障(即 mfence),
告诉编译器不要围绕障碍进行优化。
我怀疑调用树部分指的是#2。即:
int x = 0;
void foo()
x = 7;
_ReadWriteBarrier();
x = 8;
没有障碍,x=7 可以被编译器完全删除。有了屏障,它就留下来了。 现在,调用 foo 的函数怎么样?
void bar()
x = 3; // optimized away?
foo();
x = 4;
我认为过去 x=3 可能已被优化掉(编译器很难判断是否允许这样做),但现在它会正确保留 x=3 指令。
我认为。
【讨论】:
这也是我对 MS 文档的理解。但是编译器怎么可能实现这种行为呢?如果答案仅仅是所有非内联函数调用都是编译器重新排序栅栏,那么为什么对早期版本的 VC 的引用没有实现呢? 我真的不知道。它可以用链接器解释的属性标记每个函数。这可能就像他们在编译期间如何在 lib 中或至少在对象字典中进行名称修改或复杂数据库一样简单......但是,通常在过去,编译器总是假设他们无法看到的函数的最坏情况,因此不会围绕它进行优化。也许随着他们变得更聪明,他们需要公开更多信息。以上是关于_ReadWriteBarrier 如何向上传播调用树?的主要内容,如果未能解决你的问题,请参考以下文章