Я работаю над моделированием случайных движений частиц, движущихся в решетке. По этой причине я должен создать огромное количество случайных чисел, около 10 ^ 12 и выше. В настоящее время я использую возможности, предоставляемые С++ 11 с помощью <random>
. При профилировании моей программы я вижу, что в <random>
проводится большое количество времени. Подавляющее большинство этих чисел составляет от 0 до 1, равномерно распределенных. Здесь a тогда мне нужно число из биномиального распределения. Но основное внимание уделяется номерам 0..1.
Вопрос: что я могу сделать, чтобы сократить время процессора, необходимое для генерации этих чисел, и каково влияние на их качество?
Как вы можете видеть, я пробовал разные двигатели, но это не оказало большого влияния на процессорное время. Далее, в чем разница между моими uniform01(gen)
и generate_canonical<double,numeric_limits<double>::digits>(gen)
?
Изменить: Прочитав ответы, я пришел к выводу, что для моей проблемы нет идеального решения. Таким образом, я решил сначала сделать свою программу многопоточными и запустить несколько RNG в разных потоках (засеянных одним номером random_device + индивидуальным приращением потока). В настоящее время эти швы являются наиболее неизбежным шагом (в любом случае потребуется многопоточность). В качестве еще одного шага, ожидающего рассмотрения точных требований, я перехожу к предлагаемому Intel RNG или Thrust. Это означает, что моя реализация RNG не должна быть сложной, и в настоящее время это не так. Но сейчас мне нравится фокусироваться на физической корректности моей модели, а не на программировании, это происходит, как только выход моей программы физически корректен. Thrust Относительно Intel RNG
Вот что я делаю сейчас:
class Generator {
public:
Generator();
virtual ~Generator();
double rand01(); //random number [0,1)
int binomial(int n, double p); //binomial distribution with n samples with probability p
private:
std::random_device randev; //seed
/*Engines*/
std::mt19937_64 gen;
//std::mt19937 gen;
//std::default_random_engine gen;
/*Distributions*/
std::uniform_real_distribution<double> uniform01;
std::binomial_distribution<> binomialdist;
};
Generator::Generator() : randev(), gen(randev()), uniform01(0.,1.), binomial(1,1.) {
}
Generator::~Generator() { }
double Generator::rand01() {
//return uniform01(gen);
return generate_canonical<double,numeric_limits<double>::digits>(gen);
}
int Generator::binomialdist(int n, double p) {
binomial.param(binomial_distribution<>::param_type(n,p));
return binomial(gen);
}