gpt4 book ai didi

c++ - C++ 编译器会消除赋值重复吗?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:57:53 24 4
gpt4 key购买 nike

如果我有一个示例函数,例如:

void func1(float a, float b, float c)
{
setA(a);
setB(b);
setC(c);
}

调用内联函数:

inline void setA(float a){ m_a = a; m_isValid = false; }
inline void setB(float b){ m_b = b; m_isValid = false; }
inline void setC(float c){ m_c = c; m_isValid = false; }

我应该关心“m_isValid = false”重复项还是编译器通过优化消除它们?

最佳答案

是的,这通常称为 Dead Store Elimination (用编译器的说法,读取 = 加载和写入 = 存储)。

一般来说,任何无用的操作都可以被编译器优化掉,前提是它可以证明你(用户)不会注意到它(在语言设置的范围内)。

特别是对于 Dead Store Elimination,它通常仅限于:

  • 单个函数的主体(然而,内联在这里有帮助)
  • 无需干预对不透明函数的调用

一些例子:

struct Foo { int a; int b; };

void opaque(Foo& x); // opaque, aka unknown definition

Foo foo() {
Foo x{1, 2};
x.a = 3;
return x; // provably returns {3, 2}
// thus equivalent to Foo foo() { return {3, 2}; }
}

Foo bar() {
Foo x{1, 2};
opaque(x); // may use x.a, so need to leave it at '1' for now
x.a = 3;
return x;
}

Foo baz() {
Foo x{1, 2};
opaque(x);
x.a = 1; // x.a may have been changed, cannot be optimized
return x;
}

请注意,是否连续存储相同的值并不重要,只要编译器能够证明在两次存储操作之间没有读取一个变量,它就可以安全地消除第一个。

特殊情况:根据 C++ 规范,加载/存储到 volatile 无法优化。这是因为 volatile 被指定为允许与硬件交互,因此编译器无法先验地知道硬件是否会在程序背后读取或写入变量。

另一种特殊情况:出于优化的目的,在多线程程序中使用的内存同步操作(fences、barrier 等)也可以阻止这种优化。这是因为,与 volatile 情况非常相似,同步意味着另一个执行线程可能已经修改了该线程背后的变量。

最后,像所有优化一样,它的有效性在很大程度上取决于对上下文的了解。如果证明 opaque 不读取或不写入 x.a,则可以优化一些存储(如果编译器可以检查 的定义,则证明>不透明),所以一般来说它真的依赖于内联和常量传播。

关于c++ - C++ 编译器会消除赋值重复吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18430671/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com