【发布时间】:2021-01-01 10:09:03
【问题描述】:
有人可以向我解释为什么第二个 for 循环使用旧的 rand() 比第一个循环执行得快很多吗?我在这里通过多个帖子看到,推荐使用 c++11 引擎和均匀分布,因为 rand() + 多线程是性能瓶颈? 同样按照建议,我每个线程都有生成器和函数。
int main(int argc, char *argv[])
{
std::vector<mt19937> generators(omp_get_max_threads());
std::vector<uniform_real_distribution<double>> functions(omp_get_max_threads());
for (int i = 0; i < omp_get_max_threads(); i++)
{
// seed is random
generators[i] = mt19937(1654 + 17*i);
functions[i] = uniform_real_distribution<double>(0.0,1.0);
}
double itime = omp_get_wtime();
#pragma omp parallel for
for (int i =0; i < 10000000; i++)
{
int a = functions[omp_get_thread_num()](generators[omp_get_thread_num()]);
}
double end = omp_get_wtime() - itime;
srand(time(NULL));
double start = omp_get_wtime();
#pragma omp parallel for
for (int i =0; i < 10000000; i++)
{
int a = ((double) rand() / (RAND_MAX));
}
double endR = omp_get_wtime() - start;
cout << "Generator: " << end<<endl;
cout<<"Old: "<<endR << endl;
}
【问题讨论】:
-
请注意
rand可以是一个非常简单且非常不随机的 PRNG。mt19937OTOH 是一种更复杂且影响性能的算法,并提供更多的随机数。 -
简单地说,
rand不是很好。同意@NathanOliver。 -
还请注意,有比 MT 更好的 PRNG。在速度(例如每个字节的周期、缓存压力等)和统计属性(线性复杂性是最明显的)方面都更好。关于 MT 的最新论文是 arxiv.org/abs/1910.06437
-
对 omp_get_thead_num() 的 200 万次定时调用不会提高性能,而且 rand() 并行执行时的结果毫无意义。您需要将对 rand() 的调用放在关键部分中以进行公平比较。 (关于并行随机数,请查看 Parallel Random Numbers: As Easy as 1, 2, 3 thesalmons.org/john/random123/papers/random123sc11.pdf)
标签: c++ performance random parallel-processing openmp