C ++ 11并行化:Armadillo的set_seed_random()的瓶颈

时间:2018-11-08 14:19:23

标签: c++ performance c++11 parallel-processing armadillo

在C ++ 11中,使用arma_rng::set_seed_random()会产生瓶颈。我展示了一种重现它的方法。

考虑以下简单代码:

#include <armadillo>    // Load Armadillo library.
using namespace arma;

int main()
{
bool jj = true;
while ( jj == true ){
    arma_rng::set_seed_random();            // Set the seed to generate random numbers.
    double rnd_number = randu<double>();    // Generate a random number.
}

}

我用

编译
g++ -std=c++11 -Wall -g bayesian_estimation.cpp -o bayesian_estimation -O2 -larmadillo

当我在终端中运行可执行文件时,我看到一个内核正在以接近100%的CPU%处理它。如果我运行它的更多实例,则会减少每个相应进程的CPU%,但不会使用新的(和空闲!)内核。我在this question中详细说明了这种行为。

为什么会这样?

2 个答案:

答案 0 :(得分:2)

我假设Armadillo从操作系统维护的真实随机数池中获取set_seed_random()的种子(例如,大多数* NIX操作系统上的/ dev / random)。由于这需要一个熵的物理源(通常使用击键,网络事件,其他中断源的时间),因此该池是有限的,并且耗尽速度快于生成新的随机数。

在您的情况下,我将假设一个全速运行的可执行文件正在以与添加新熵大致相同的速率消耗池。一旦添加第二个,第三个...,它们就会在等待新的随机数进入池中时停滞。

答案 1 :(得分:0)

看看伪随机数生成器的代码,您会发现实例化它和/或为其提供新种子可能是一个相当昂贵的过程。通常,您应该只为每个线程实例化/设置一个,并在剩余的线程寿命中使用它。

np.array(df[1].values.tolist())

除非定义了#include <armadillo> // Load Armadillo library. using namespace arma; int main() { bool jj = true; arma_rng::set_seed_random(); // Set the seed to generate random numbers. while ( jj == true ){ double rnd_number = randu<double>(); // Generate a random number. } } ,否则arma_rng::set_seed_random()似乎使用了各种后备。我的猜测是尝试ARMA_USE_CXX11时会很幸运。进行/dev/urandom以获得更多有关此的信息。