0

我有一个prob.h这样声明的类:

struct A_s{
    int a, b;
}

class A_c{
    private:
        std::vector<A_s> vec_of_A_s;
    public:
        int vec_of_A_s_size() const{return static_cast<int>(vec_of_A_s.size());}
}

A_c A;//A is an object of class A_c我的实现文件的其他地方.cpp,我有以下行:

for(int i = 0; i < A.vec_of_A_s_size(); i++) {...//do loop stuff}

我从我的程序设计中知道A.vec_of_A_s_size()是循环不变的。但是,我真的想避免以下情况(这很麻烦):

int sz = A.vec_of_A_s_size();
for(int i = 0; i < sz; i++) {...//do loop stuff}

我能否充分且始终如一地依赖一个编译器,即启用了优化 (-O2) 的发布版本不会vec_of_A_s.size()每次都进行评估?

这是我已经尝试过的问题:

(1)(请参阅下面的编辑更新)即使使用调试版本,使用 options -fPIC -fno-strict-aliasing -fexceptions -g -std=c++14,查看反汇编程序输出,vec_of_A_s.size()也只评估一次。但是,编译器会始终如一地可靠地进行这种优化吗?有任何已知的例外吗?我的怀疑和需要保证的部分原因源于下面的问题(2)。

(2)我查看了关于 SO:Performance issue for vector::size() in a loop的相关问题。那里的问题直接评估循环中向量的大小,如下所示:

for(int i = 0; i < vec_of_A_s.size(); i++) {...//do loop stuff}

就我而言,该向量不能直接访问。它是一个私有成员,A_c它的大小只能通过公共成员函数访问A.vec_of_A_s_size()。因此,在 for 循环中必须发生额外的间接/重定向层。该线程上的答案似乎表明编译器确实会优化循环不变量。但是在向量的大小不能直接和公开获得的情况下(如上),编译器会可靠地保证循环不变优化吗?

(3)在关于此类问题的其他相关问题中,一个常见的答案似乎是对程序进行剖析。如果以及当我进行分析时,我究竟应该寻找什么来验证这个特定的优化?该代码是更大的数值分析代码的一部分,这绝对不是当前的瓶颈。然而,很高兴知道如何在分析器中验证这一点。如果这个问题 (3) 太宽泛,我们深表歉意。我对分析比较陌生。但是分析器是否允许分析单个函数,比如包含上述for循环的函数?这样,我可以确定与此功能有关的瓶颈在哪里。


编辑更新:

在 (1) 上,使用所述编译器选项的调试构建优化循环不变量是不正确的。我错了。在更深入的挖掘中,事实证明该函数确实被调用了两次。

4

1 回答 1

1

如果你的循环在向量上调用了一个非常量的方法,那么我几乎可以肯定地说所有的赌注都没有了。

如果你只在向量上调用 const 方法,那么你可能希望得到优化,但由于标准不需要它们,你不能真的责怪编译器没有做出对你来说可能很明显的优化,

鉴于您可以在 for 循环中声明多个变量,只要它们属于同一类型,将 sz 带入循环似乎是显而易见的事情。或者,您可以向后运行循环吗?

于 2018-02-11T18:48:35.350 回答