与 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 中有 memory order,内存顺序可以帮助解决这个问题吗?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)