随机数生成器的性能因平台而异 [英] Random number generator performance varies between platforms

查看:133
本文介绍了随机数生成器的性能因平台而异的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在测试c ++中随机数生成器的性能,并且遇到了一些我不理解的非常奇怪的结果.

I am testing the performance of random number generators in c++ and have come upon some very strange results that I do not understand.

我已经测试了使用std :: minstd_rand的std :: rand与std :: uniform_real_distribution.

I have tested std::rand vs std::uniform_real_distribution which uses std::minstd_rand.

用于计时std :: rand的代码

Code for timing std::rand

auto start = std::chrono::high_resolution_clock::now();

for (int i = 0; i < 1000000; ++i)
    std::rand();

auto finish = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed = finish - start;
std::cout << "Elapsed time: " << elapsed.count() * 1000 << " ms\n";

使用std:minstd_rand计时std :: uniform_real_distribution的代码

Code for timing std::uniform_real_distribution with std:minstd_rand

std::minstd_rand Mt(std::chrono::system_clock::now().time_since_epoch().count());
std::uniform_real_distribution<float> Distribution(0, 1);

auto start = std::chrono::high_resolution_clock::now();

for (int i = 0; i < 1000000; ++i)
    Distribution(Mt);

auto finish = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed = finish - start;
std::cout << "Elapsed time: " << elapsed.count() * 1000 << " ms\n";

在使用Microsoft Visual Studio 2019进行编译时,在Dell Latitude 7390(I7-8650U 1.9Ghz)上,我得到以下速度:

When compiling with Microsoft Visual Studio 2019, on a Dell Latitude 7390 (I7-8650U 1.9Ghz) I get the following speeds:

std :: rand->经过的时间:45.7106毫秒 std :: uniform_real_distribution->经过时间:65.7437毫秒

std::rand -> Elapsed time: 45.7106 ms std::uniform_real_distribution -> Elapsed time: 65.7437 ms

我使用-D__FMA__的附加命令行选项打开了编译器优化功能.

I have compiler optimizations turned on with the additional command line option of -D__FMA__

但是,在MacOS High Sierra(1.4Ghz i5)的MacBook Air上使用g ++进行编译时,我得到以下速度:

However when compiling with g++ on a MacBook Air on MacOS High Sierra (1.4Ghz i5) I get the following speeds:

std :: rand->经过的时间:9.4547毫秒 std :: uniform_real_distribution->经过时间:7.9e-05 ms

std::rand -> Elapsed time: 9.4547 ms std::uniform_real_distribution -> Elapsed time: 7.9e-05 ms

使用终端命令"g ++ prng.cpp -o prng -std = c ++ 17 -O3"

using terminal command "g++ prng.cpp -o prng -std=c++17 -O3"

另一个问题是,在Mac上,如果我打印了/不打印该值,则测试uniform_real_distribution的速度会有所不同.

Another problem was that on Mac, testing the speed of uniform_real_distribution the speed would vary if I did / did not print the value.

所以

std::minstd_rand Mt(std::chrono::system_clock::now().time_since_epoch().count());
std::uniform_real_distribution<float> Distribution(0, 1);

float num;

auto start = std::chrono::high_resolution_clock::now();

for (int i = 0; i < 1000000; ++i)
    num = Distribution(Mt);

auto finish = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed = finish - start;
std::cout << "Elapsed time: " << elapsed.count() * 1000 << " ms\n";
std::cout << num << '\n';

给我5.82409毫秒的时间

would give me time of 5.82409 ms

不打印则得到7.9e-05毫秒,请注意,打印仅影响uniform_real_distribution的测试,而我不需要对std :: rand进行此操作.我还使用mersenne进行了测试,而不是没有遇到相同的问题.

whereas without printing I get 7.9e-05 ms, Note that printing only effects the test for uniform_real_distribution, I do not need to do this for std::rand. I also tested using mersenne instead of which does not suffer from the same issue.

我本来以为这是编译器优化,因为未使用/未打印变量,所以在未存储/打印时省略了uniform_real_distribution,因此可以省略,但是为什么编译器不对std :: rand做同样的事情,为什么这些随机函数在Mac上的运行速度比Windows快?

I originally thought that this was compiler optimizations omitting the uniform_real_distribution when it wasn't stored / printed as the variable isn't used and thus can be omitted but then why doesn't the compiler do the same for std::rand, and why do these random functions run faster on Mac than Windows?

为了澄清起见,mersenne指的是std :: mt19937_64而不是std :: minstd_rand,以表示"uniform_real_distribution".

For clarification mersenne is referring to std::mt19937_64 being used instead of std::minstd_rand for uniform_real_distribution.

推荐答案

C ++标准库中的所有发行版(包括uniform_real_distribution)都使用实现定义的算法. (std::rand同样适用,它遵循C标准的rand函数.)因此,很自然地,在C ++标准库的不同实现中,这些发行版之间的性能会有差异.另请参见此答案.

All of the distributions in the C++ standard library (including uniform_real_distribution) use an implementation-defined algorithm. (The same applies to std::rand, which defers to the C standard's rand function.) Thus, it's natural that there would be performance differences between these distributions in different implementations of the C++ standard library. See also this answer.

您可能想尝试测试C ++随机引擎(例如std::minstd_randstd::mt19937)是否存在性能差异,它们确实在C ++标准中指定了固定算法.为此,请直接在引擎中生成一个随机数,而不要通过任何C ++发行版(例如uniform_int_distributionuniform_real_distribution)来生成随机数.

You may want to try testing whether there are performance differences in the C++ random engines (such as std::minstd_rand and std::mt19937), which do specify a fixed algorithm in the C++ standard. To do so, generate a random number in the engine directly and not through any C++ distribution such as uniform_int_distribution or uniform_real_distribution.

我本来以为这是编译器优化,因为未使用/未打印变量,所以在未存储/打印时省略了uniform_real_distribution,因此可以省略,但是为什么编译器不对std :: rand做同样的事情[?]

I originally thought that this was compiler optimizations omitting the uniform_real_distribution when it wasn't stored / printed as the variable isn't used and thus can be omitted but then why doesn't the compiler do the same for std::rand[?]

我认为编译器可以执行此优化,因为在实践中,C ++标准库是作为可用于编译器的C ++代码实现的,因此编译器可以根据需要对该代码执行某些优化.这与std::rand有所不同,std::rand仅作为其实现对于编译器不可用的函数来实现,从而限制了编译器可以进行的优化.

I presume the compiler could do this optimization because in practice, the C++ standard library is implemented as C++ code that's available to the compiler, so that the compiler could perform certain optimizations on that code as necessary. This is unlike with std::rand, which is only implemented as a function whose implementation is not available to the compiler, limiting the optimizations the compiler could do.

这篇关于随机数生成器的性能因平台而异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆