Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 定义概率分布代价高昂吗?_C++_Optimization_Probability - Fatal编程技术网

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