【问题标题】:Do modern C++ compilers optimize away repeated accesses to the same data member of a class?现代 C++ 编译器是否优化了对类的同一数据成员的重复访问?
【发布时间】:2019-12-31 13:47:59
【问题描述】:

考虑:

class A
{
public:
    const int& my_int_member() const { return my_int_member; }
    const double& my_double_member const {return my_double_member; }
private:
    int my_int_member;
    double my_double_member;
};

class B
{
public:
    const A& my_A_member() const { return my_A_member; }
private:
    A my_A_member;
};

现代 c++ 编译器(例如 msvc、clang、gcc)设置每个提供的最大优化级别,通常会识别和优化对相同数据成员的重复访问,如下所示:

B b;
do_stuff(b.my_A_member().my_double_member(), b.my_A_member().my_int_member());
double c = b.my_A_member().my_double_member() + b.my_A_member().my_int_member();

也就是说,他们是否意识到他们可以重复使用相同的引用,或者他们只是再次进行访问?

【问题讨论】:

  • 你可以试试看这里:godbolt.org。如果不是,我会感到惊讶
  • 实际上我希望一个体面的编译器能够为最后一行创建与 double c = 0; 等效的内容
  • 也许吧。不可能给出一个笼统的答案。这取决于编译器/优化器是如何实现的——它寻找删除重复访问的机会的积极程度,以及如果找到机会它会做什么。编译器供应商通过不同的做事(包括优化)来竞争,每个做事都比竞争对手更好地适合某些用户(开发人员)。但是没有编译器(还)对一切都是完美的。唯一可以确定的方法是,对于您选择的编译器和优化设置,检查编译器的输出。

标签: c++ optimization compilation


【解决方案1】:

如果定义是可见的,并且如果编译器可以证明它做了同样的事情(使用 as-if 规则进行优化)(这更棘手,我们可以使用别名、全局访问......),它可以做到(而且可能做到了)。

但想象一下,我们将您的示例稍微修改为(b 不再是本地的,而是作为参数给出):

void foo(B& b)
{
    do_stuff(b.my_A_member().my_double_member(), b.my_A_member().my_int_member());
    double c = b.my_A_member().my_double_member() + b.my_A_member().my_int_member();
}

do_stuff 可以修改全局B,这将是foo 的参数。 没有定义,答案是肯定的。 所以编译器必须在调用do_stuff之后重新加载b.my_A_member()

为了可读性,我还是会这样做:

B b;
const auto& a = b.my_A_member();
do_stuff(a.my_double_member(), a.my_int_member());
double c = a.my_double_member() + a.my_int_member();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-19
    • 2019-04-29
    • 2017-06-26
    • 1970-01-01
    • 2014-04-18
    • 2011-03-18
    • 1970-01-01
    相关资源
    最近更新 更多