定义概率分布的成本是否很高
Is defining a probability distribution costly?
我正在编写物理模拟,现在我觉得需要优化它。我正在考虑改进一点:我的一个类的方法之一(我在几种情况下调用了十亿次)定义了每次概率分布。这是代码:
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
}
我可以将发行版作为类的成员传递,这样我就不必每次都定义它们吗?只需在构造函数中初始化它们并在 h 和 v 更改时重新定义它们?这能是一个很好的优化进度吗?最后一个问题,当使用标志 -O3 或 -O2 编译时,编译器(在我的例子中为 g++)是否已经纠正了?
提前谢谢你!
更新:我对其进行了编码并计时:程序实际上变慢了一点(百分之几),所以我回到了我开始的地方:在每个循环中创建概率分布
答案 A:我不应该这么认为,对于均匀分布,它只是将参数值复制到适当的位置,也许使用少量的算术,这将得到很好的优化。
但是,我相信分布对象可以具有状态。它们可以使用调用生成器的部分随机数据,并允许保存其余的随机性,以便下次使用分布时使用,以减少对生成器的调用总数。因此,当您销毁分发对象时,您可能会丢弃一些可能代价高昂的随机数据。
答案B:停止猜测并测试它。
对代码进行计时,然后将static
添加到probd
的定义中,然后再次计时。
- 是的
- 是的
- 嗯,可能有一些优势,但 AFAIK 这些对象并不是真正的重量级/构建成本。此外,对于局部变量,您可能会在数据局部性和优化器可以做出的假设中获得一些东西。
- 我不认为它们会自动作为类变量移动(特别是如果你的类是 POD - 在这种情况下,我怀疑编译器是否敢于修改其布局);最有可能的是,相反,它们被完全优化了 - 只有被调用方法的代码 - 特别是 operator() - 可能保留,直接引用 h 和 v。但这必须通过查看生成的程序集来检查。
顺便说一下,如果你有性能问题,除了优化明显的点(内部循环中使用的非最优算法,连续内存分配,删除大对象的无用副本,...),你应该真正尝试使用探查器来找到代码中真正的"热点",并集中精力优化它们,而不是随机浏览所有代码。
>uniform_real_distribution
保持类型为 param_type
的状态,该状态是两个double
值(使用默认模板参数)。构造函数分配给这些,否则是微不足道的,析构函数是微不足道的。
因此,与初始化 1 个指针(或引用)或通过 this
间接寻址相比,在函数中构造临时值具有存储 2 个double
值的开销。从理论上讲,它可能因此更快(尽管看起来更快的东西,或者运行得更快有意义的东西没有必要更快)。由于工作量不大,因此当然值得尝试和计时是否存在差异,即使是微优化。
一些额外的3-4个周期通常可以忽略不计,但既然你说的是"数十亿次",它当然可以很好地产生可衡量的差异。 3 个周期乘以 10 亿是 3GHz 机器上的 1 秒。
当然,没有分析的优化总是有点...尴尬。您可能会发现,代码中调用数十亿次的不同部分可以节省更多的周期。
编辑:
由于您不打算修改它,并且由于第一个发行版是用文字值初始化的,因此您实际上可以将其设置为常量(例如constexpr
或命名空间级别static const
)。无论其他两个如何,这都应该允许编译器在任何情况下为该编译器生成最有效的代码。
- 在提升multi_index容器中,是否定义了"default index"?
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 检查输入是否不是整数或数字
- 是否可以初始化不可复制类型的成员变量(或基类)
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- c++在循环中定义一组概率分布
- 如何测试某些数字是否沿区间均匀分布?
- 是否有在 c++ 中使用三角分布生成随机数的函数
- 如何输出特定值 x 处 gamma 分布的概率密度?在C++
- 定义概率分布的成本是否很高
- 模拟退火,如何规范化概率分布
- 如何计算 CDF C++中正态分布概率
- 如何有效地处理不同的概率分布函数
- C++ - 临界值概率分布
- 为概率分布的数据表示寻求建议
- 具有频繁变化概率的c++离散分布抽样
- 我是否应该保留随机分布对象实例,或者我可以总是重新创建它
- C++中具有概率分布的向量的随机生成器
- 将概率分布拟合到观测数据c++
- 是否遵循均匀分布::random_device 和 std::mt19937