Распараллеливание в C ++ 11: узкое место в set_seed_random () от Armadillo - PullRequest
0 голосов
/ 08 ноября 2018

В 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

Когда я запускаю исполняемый файл в терминале, я вижу, что одно из ядер обрабатывает его с CPU%, близким к 100%. Если я запускаю больше его экземпляров, CPU% каждого соответствующего процесса уменьшается, но новые (и бездействующие!) Ядра не используются. Я подробно проиллюстрирую такое поведение в этом вопросе .

Почему это происходит?

Ответы [ 2 ]

0 голосов
/ 08 ноября 2018

Взгляните на код генератора псевдослучайных чисел, и вы поймете, что создание его и / или предоставление ему нового начального числа может быть довольно дорогостоящим процессом. Обычно вы должны только создавать / seed one для каждого потока и использовать его для остальной части жизни потоков.

#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. Сделайте man urandom для получения дополнительной информации об этом.

0 голосов
/ 08 ноября 2018

Я бы предположил, что Armadillo берет начальное значение для set_seed_random() из пула истинных случайных чисел, который поддерживается ОС (например, / dev / random в большинстве * ОС NIX). Поскольку для этого требуется физический источник энтропии (обычно используется время нажатия клавиш, сетевых событий, других источников прерываний), этот пул конечен и может быть исчерпан быстрее, чем могут быть сгенерированы новые случайные числа.

И в вашем случае я бы предположил, что один исполняемый файл, работающий на полной скорости, истощает пул примерно с той же скоростью, что и новая энтропия. Как только вы добавите второе, третье, ..., они останавливаются в ожидании поступления новых случайных чисел в пул.

...