当前位置: 首页 > 知识库问答 >
问题:

编译器能优化出两个原子负载吗?[副本]

东方华荣
2023-03-14
void run1() {
    auto a = atomic_var.load(std::memory_order_relaxed);
    auto b = atomic_var.load(std::memory_order_relaxed);
   // Some code using a and b;
}

void run2() {
    if (atomic_var.load(std::memory_order_relaxed) == 2 && /*some conditions*/ ...) {
         if (atomic_var.load(std::memory_order_relaxed) * somevar > 3) {
               /*...*/
         }
    }
}

run1()run2()是使用同一原子变量的两个加载的两个场景。编译器可以将两个加载的场景折叠为一个加载并重用它吗?

共有1个答案

邵繁
2023-03-14

run1()的实现可以安全地优化为

void run1() {
    auto a = atomic_var.load(std::memory_order_relaxed);
    auto b = a;
   // Some code using a and b;
}

在原始程序中,这两个加载可能按照每次调用run1()时对atomic_var访问的总顺序相邻。在这种情况下,相邻的load()操作将返回相同的结果。

由于不能排除这种可能性,编译器可以优化掉第二个load()。对于任何内存顺序参数都可以做到这一点,而不仅仅是对于松弛的原子。

 类似资料:
  • 问题内容: 假设我在C代码中有类似的内容。我知道您可以使用a 代替,以使编译器不对其进行编译,但是出于好奇,我问编译器是否也可以解决此问题。 我认为这对于Java编译器来说更为重要,因为它不支持。 问题答案: 在Java中,if内的代码甚至都不是已编译代码的一部分。它必须编译,但不会写入已编译的字节码。它实际上取决于编译器,但我不知道没有对它进行优化的编译器。规则在JLS中定义: 优化的编译器可能

  • 我有一个。为简单起见,假设 s 占据范围 -2^31 到 2^31-1。我想计算。我允许 是任何值 0 一种解决方案是计算< code>2*(x-1) 1。比我想要的多了一个减法,但是这个不应该溢出来。但是,编译器会将其优化为< code>2*x-1。这是源代码的问题吗?这是可执行文件的问题吗? 以下是 的弩线输出: 以下是 的闩线输出:

  • [原文][1] 在我的服务器类中,我想读取文本文件的每一行,包括空行,但它从文件的中间开始。我相信这与ecplise最大输出有关。我知道是因为我从每一行得到正确的字节输出。

  • 我经常遇到这种情况。乍一看,我认为,“这是糟糕的编码;我正在执行一个方法两次,必然会得到相同的结果。”但想到这里,我不得不怀疑编译器是否像我一样聪明,并能得出相同的结论。 编译器的行为是否取决于 方法的内容?假设它看起来像这样(有点类似于我现在的真实代码): 除非对这些对象来自的任何存储进行处理不当的异步更改,否则如果连续运行两次,肯定会返回相同的内容。但是,如果它看起来像这样(为了论证而无意义的

  • 什么平均负载 简单来说,平均负载是指单位时间内,系统处于可运行状态和不可中断状态的平均进程数,也就是平均活跃进程数,它和 CPU 使用率并没有直接关系。 所谓可运行状态的进程,是指正在使用 CPU 或者正在等待 CPU 的进程,也就是我们常用 ps 命令看到的,处于 R 状态(Running 或 Runnable)的进程。 不可中断状态的进程则是正处于内核态关键流程中的进程,并且这些流程是不可打断

  • 如果关闭了编译器优化(gcc-o0...),那么说'volatile'关键字没有区别是可以的吗? 我制作了一些示例“C”程序,并且仅当打开编译器优化时,才在生成的汇编代码中看到易失性和非易失性之间的区别,即((gcc-o1....)。