Хранение списка RNG в std :: массив для многопоточного чтения
Вопрос
Я хотел бы многопоточно, мою часть RNG моего кода, используя C ++ 11.
Я создаю кучу RNG, как это:
typedef std::mt19937 mersenne_twister;
typedef std::uniform_real_distribution<double> unidist;
// 8 rng engines with 8 consecutive seeds
const size_t Nrng = 8;
const array<uint32_t,Nrng> seed_values = {0,1,2,3,4,5,6,7};
array<mersenne_twister,Nrng> engines;
const array<unidist,Nrng> distributions; // default constructor is for [0,1] interval
const array<????,Nrng> rngs; // What type do I put here?
for( size_t i=0; i<Nrng; ++i )
engines[i].seed(seed_values[i]);
rngs[i] = std::bind(distributions[i], engines[i]);
С идеей, которую я позже смогу передать каждый из объектов RNG в отдельный std::thread
это заполняет другой array
с некоторыми формами случайных чисел с использованием поставляемого генератора. Я не знаю, какой тип мне нужно использовать для RNG array
. Анкет Я знаю, как создать один RNG, как так:
auto rng = std::bind(unidist, generator);
Но мне нужно явно иметь (decltype
D?) Тип для array
.
Решение
Одним из возможных типов было бы std::function<double()>
, но обратите внимание, что это не бесплатно. Фактический тип результата bind
непостижимо, и поэтому вы не можете просто сделать контейнер с типом элемента decltype(std::bind(...))
, поскольку типы не гарантируются взаимно конвертируемыми - все, что вы знаете, это то, что все они конвертируются в function
.
Если это критично, я предлагаю вам профилировать и сравнить стоимость std::function
к прямому использованию unidist(rngs[i])
в вашем целевом коде. (Распределение - это адаптер без сохранения состояния, который в любом случае должен быть повторно, поэтому вам не нужно хранить его более одного копии.)