c++ - 与 asm volatile 相比,我们需要使用一些运行时内存围栏机制
问题描述
假设我们有这样一段 c++ 代码:
auto t1 = getSystemTime(); // Statement 1
foo(); // Statement 2
auto t2 = getSystemTime(); // Statement 3
auto elapsedTime = t2 - t1;
据我了解,编译器可能会优化代码,这意味着它只有在不违反 as-if 规则的情况下才可能重新排序执行顺序。比如下面代码的执行顺序
c = a + b;
d = e + f;
可以重新排序为
d = e + f;
c = a + b;
因此,上面的代码可以重新排序如下:
auto t1 = getSystemTime(); // Statement 1
auto t2 = getSystemTime(); // Statement 3
foo(); // Statement 2
auto elapsedTime = t2 - t1;
这会产生完全不同的结果。
在谷歌搜索这个问题后,我得到了这个:__asm__ __volatile__ ("" ::: "memory");
. 如果我是对的,通过这一行,我们可以禁用编译器的优化,这样执行顺序就不会被重新排序。
如果我正确使用它,代码将如下所示:
__asm__ __volatile__ ("" ::: "memory");
auto t1 = getSystemTime(); // Statement 1
foo(); // Statement 2
auto t2 = getSystemTime(); // Statement 3
auto elapsedTime = t2 - t1;
但是,在阅读了一些文档后,我发现这__asm__ __volatile__ ("" ::: "memory");
只是编译时,而不是运行时。
现在我很困惑。如果__asm__ __volatile__ ("" ::: "memory");
仅在编译时工作,是否意味着它完全没用,因为执行顺序仍然可以在运行时更改?如果是这样,是否有其他机制来禁止在运行时重新排序?或者没有任何其他机制,因此执行顺序仍然可以在运行时重新排序,但__asm__ __volatile__ ("" ::: "memory");
我们可以降低重新排序的概率?
此外,我们在 C++11 中有内存顺序,内存顺序可以帮助解决这个问题吗?
解决方案
推荐阅读
- javascript - 我可以创建一个 chrome 扩展,当我转到某些 url 时,它将重定向到我计算机上的 html 文档?
- angularjs - Angular JS 中的空白自定义指令,我指的是这个 https://www.youtube.com/watch?v=R_okHflzgm0
- html-table - 如何使 ag-Grid 表响应以使标题和行被转置?
- ssl - 在使用 TestCafe 时尝试登录 gmail
- javascript - GlobalContext 未在类组件中更新
- vue.js - 仅在 v-for 中显示关联数据
- reactjs - 反应 router-dom以传递多个参数并使用 useParams 访问它们
- python - 将简单 JSON 转换为 pandas 数据框
- python - Python eval() 将 UserDict 类型更改为 dict
- python - while 循环中有两个 False