C++ 定义概率分布代价高昂吗?
我正在编写一个物理模拟程序,我现在觉得有必要对它进行优化。我在考虑改进一点:我的一个类的一个方法(在一些情况下我调用了十亿次)定义了每次概率分布。代码如下:C++ 定义概率分布代价高昂吗?,c++,optimization,probability,C++,Optimization,Probability,我正在编写一个物理模拟程序,我现在觉得有必要对它进行优化。我在考虑改进一点:我的一个类的一个方法(在一些情况下我调用了十亿次)定义了每次概率分布。代码如下: void myClass::myMethod(){ //called billions of times in several cases uniform_real_distribution<> probd(0,1); uniform_int_distribution<> probh(1,h-2); uniform_
void myClass::myMethod(){ //called billions of times in several cases
uniform_real_distribution<> probd(0,1);
uniform_int_distribution<> probh(1,h-2);
uniform_int_distribution<> probv(1,v-2);
//rest of the code
}
void myClass::myMethod(){//在几种情况下调用了数十亿次
均匀实分布probd(0,1);
均匀分布概率h(1,h-2);
均匀分布概率v(1,v-2);
//代码的其余部分
}
我可以作为类的成员传递分发,这样我就不必每次都定义它们了吗?然后在构造函数中初始化它们,当h和v改变时重新定义它们?这会是一个很好的优化过程吗?最后一个问题,当使用-O3或-O2标记编译时,编译器(在我的例子中是g++)是否已经纠正了它
提前谢谢你
更新:我对它进行了编码并对两者进行了计时:程序实际上变慢了一点(几个百分点),所以我回到了我开始的地方:在每个循环创建概率分布,这将得到很好的优化 但是,我相信分布对象可以具有状态。它们可以使用来自对生成器的调用的部分随机数据,并允许保存其余的随机数据,以便在下次使用分发时使用,以减少对生成器的调用总数。因此,当您销毁分发对象时,可能会丢弃一些可能代价高昂的随机数据 回答B:别猜了,试试看
对代码计时,然后将
静态添加到probd
的定义中,并再次计时。回答A:我不这么认为,为了均匀分布,它只需将参数值复制到位,可能需要少量的算术运算,这将得到很好的优化
但是,我相信分布对象可以具有状态。它们可以使用来自对生成器的调用的部分随机数据,并允许保存其余的随机数据,以便在下次使用分发时使用,以减少对生成器的调用总数。因此,当您销毁分发对象时,可能会丢弃一些可能代价高昂的随机数据
回答B:别猜了,试试看
对代码计时,然后将static
添加到probd
的定义中,然后再次计时
对
对
嗯,这可能有一些优势,但这些物体并不是真的很重/昂贵。此外,使用局部变量,您可能会在数据局部性和优化器可以做出的假设方面获得一些好处李>
我不认为它们会自动作为类变量移动(特别是如果您的类是POD,那么我怀疑编译器是否敢修改它的布局);最有可能的是,它们被完全优化掉了——只有被调用方法的代码——特别是操作符()——可以保留下来,直接引用h和v。但这必须通过查看生成的程序集来检查李>
顺便说一句,如果您有性能问题,除了优化明显的点(内部循环中使用的非优化算法、连续内存分配、删除大对象的无用副本等),您还应该尝试使用分析器来查找代码中真正的“热点”,集中精力优化它们,而不是随机地浏览所有代码
对
对
嗯,这可能有一些优势,但这些物体并不是真的很重/昂贵。此外,使用局部变量,您可能会在数据局部性和优化器可以做出的假设方面获得一些好处李>
我不认为它们会自动作为类变量移动(特别是如果您的类是POD,那么我怀疑编译器是否敢修改它的布局);最有可能的是,它们被完全优化掉了——只有被调用方法的代码——特别是操作符()——可以保留下来,直接引用h和v。但这必须通过查看生成的程序集来检查李>
顺便说一句,如果您有性能问题,除了优化明显的点(内部循环中使用的非优化算法、连续内存分配、删除大对象的无用副本等),您还应该尝试使用分析器来查找代码中真正的“热点”,集中精力优化它们,而不是随机地浏览所有代码 uniform\u real\u distribution
维护类型为param\u type
的状态,该状态为两个double
值(使用默认模板参数)。构造器分配给这些函数,否则是平凡的,析构函数是平凡的
因此,与初始化1个指针(或引用)或通过此
执行间接寻址相比,在函数中构造一个临时函数需要存储2个双
值。从理论上讲,它可能因此更快(不过,看起来更快的东西,或者说跑得更快更有意义的东西并不一定要更快)。因为这不需要太多的工作,所以无论是否有差异,都值得尝试和确定时间,即使这是一个微观优化
一些3-4个额外的周期通常是可忽略的,但既然你说的是“数十亿次”,它当然可能会产生可测量的差异。在3GHz机器上,3个周期乘以10亿是1秒
当然,没有分析的优化总是有点。。。令人尴尬的您可能会发现,代码中另一个被称为数十亿次的部分可以节省更多的周期
编辑:
因为您不打算修改它,而且因为第一个发行版是用文本值初始化的,所以您实际上可能会将它变成一个co