如何防止gcc优化C中的一些语句?

Zel*_*luX 95 c gcc

为了使页面变脏(打开页表项中的脏位),我触摸页面的第一个字节,如下所示:

pageptr[0] = pageptr[0];
Run Code Online (Sandbox Code Playgroud)

但在实践中,gcc将忽略死店淘汰的陈述.为了防止gcc优化它,我重新编写语句如下:

volatile int tmp;
tmp = pageptr[0];
pageptr[0] = tmp;
Run Code Online (Sandbox Code Playgroud)

似乎这个伎俩有效,但有点难看.我想知道是否有任何指令或语法具有相同的效果?而且我不想使用-O0旗帜,因为它也会带来很大的性能损失.

Plo*_*low 172

您可以使用

#pragma GCC push_options
#pragma GCC optimize ("O0")

your code

#pragma GCC pop_options
Run Code Online (Sandbox Code Playgroud)

自GCC 4.4以来禁用优化.

如果您需要更多详细信息,请参阅GCC文档.

  • 然而值得注意的是,这仅适用于整个功能,而不适用于特定的语句:https://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/Function-Specific-Option-Pragmas.html“每个功能在这一点之后定义的就好像为该函数指定了属性((优化(“字符串”)))。”。 (10认同)

FRo*_*Rob 120

您也可以__attribute__((optimize("O0")))根据自己的需要使用新的pragma,而不是使用新的pragma .这具有仅应用于单个函数而不是应用于同一文件中的所有函数的优点.

用法示例:

void __attribute__((optimize("O0"))) foo(unsigned char data) {
    // unmodifiable compiler code
}
Run Code Online (Sandbox Code Playgroud)

  • 如果我没有使用`-Olevel`选项但我使用的是个人选项,那么该怎么办呢?*(在我的情况下,我无法确定哪个是打破代码的个别优化选项)*. (3认同)

Die*_*Epp 82

关闭优化可以解决问题,但这是不必要的.更安全的替代方法是使编译器通过使用volatile类型限定符来优化存储是非法的.

// Assuming pageptr is unsigned char * already...
unsigned char *pageptr = ...;
((unsigned char volatile *)pageptr)[0] = pageptr[0];
Run Code Online (Sandbox Code Playgroud)

volatile类型限定符指示编译器要严格有关内存存储和加载.一个目的volatile是让编译器知道内存访问有副作用,因此必须保留.在这种情况下,存储具有导致页面错误的副作用,并且您希望编译器保留页面错误.

这样,周围的代码仍然可以进行优化,并且您的代码可以移植到其他不了解GCC #pragma__attribute__语法的编译器.

  • @Shocker:GCC 仍然可以优化变量而不优化实际的内存访问。这些是不同的问题。 (4认同)
  • Dietrich Epp的解决方案不适用于**ARM4.1编译器**.甚至ZelluX的解决方案也无效.使这项工作适用于ARM4.1的另一种方法是在ZelluX的解决方案中,使'**temp**'成为**全局易变量**. (3认同)
  • 我会说这比关闭优化更可取。您仍然可以使用此方法从其他优化中受益。 (2认同)
  • 这对所说的编译器来说非常糟糕。 (2认同)
  • *“易失性的一个目的是让编译器知道内存访问有副作用......”* - 在 GCC 下事实并非如此。GCC 人员表示“易失性”的目的是用于内存映射硬件。来自 Ian Lance Taylor 的博客 [易失性](https://www.airs.com/blog/archives/154): *“总而言之,如果您将易失性用于操作内存映射硬件以外的任何用途,或者用于非常有限的用途线程之间的通信,很可能你犯了一个错误。仔细想想 volatile 意味着什么,不意味着什么。”* (2认同)
  • @jww:此用法符合该博客文章中描述的内容.`volatile`意味着内存访问必须按写入方式进行,这正是我们想要的.换句话说,我们仔细考虑了它,它意味着我们认为它意味着什么. (2认同)