我在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)(请参阅下面的编辑更新)即使使用带有选项-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
循环的函数?这样,我就可以确定瓶颈与这个功能有关。
修改更新:
On(1),使用所述编译器选项的调试版本不是优化循环不变量。我错了。在更深入的挖掘中,事实证明该函数确实被调用了两次。
答案 0 :(得分:1)
如果你的循环在向量上调用非常量方法,那么我肯定会确定所有的赌注都已关闭。
如果你只在向量上调用const方法,那么你可能希望进行优化,但由于标准不需要它们,你不能真正责怪编译器没有进行对你来说显而易见的优化,
鉴于你可以在for循环中声明多个变量,只要它们属于同一类型,将sz引入循环似乎是显而易见的事情。或者,你可以向后运行循环吗?