nam*_*ame 2 c++ random performance c++17
我正在 C++ 中测试随机数生成器的性能,并得到了一些我不明白的非常奇怪的结果。
我已经测试了 std::rand 与使用 std::minstd_rand 的 std::uniform_real_distribution 。
计时 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";
Run Code Online (Sandbox Code Playgroud)
使用 std:minstd_rand 计时 std::uniform_real_distribution 的代码
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";
Run Code Online (Sandbox Code Playgroud)
使用 Microsoft Visual Studio 2019 进行编译时,在 Dell Latitude 7390 (I7-8650U 1.9Ghz) 上,我获得以下速度:
std::rand -> 经过时间:45.7106 ms std::uniform_real_distribution -> 经过时间:65.7437 ms
我使用 -D__FMA__ 的附加命令行选项打开了编译器优化
但是,在 MacOS High Sierra (1.4Ghz i5) 上的 MacBook Air 上使用 g++ 进行编译时,我得到以下速度:
std::rand -> 经过时间:9.4547 ms std::uniform_real_distribution -> 经过时间:7.9e-05 ms
使用终端命令“g++ prng.cpp -o prng -std=c++17 -O3”
另一个问题是,在 Mac 上,测试 uniform_real_distribution 的速度,如果我打印/不打印值,速度会有所不同。
所以
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';
Run Code Online (Sandbox Code Playgroud)
会给我 5.82409 毫秒的时间
而没有打印,我得到 7.9e-05 毫秒,请注意,打印仅影响uniform_real_distribution 的测试,我不需要为 std::rand 执行此操作。我还使用 mersenne 进行了测试,而不是没有遇到同样的问题。
我最初认为这是编译器优化省略了 Uniform_real_distribution 当它没有被存储/打印时,因为变量没有被使用,因此可以省略,但是为什么编译器不对 std::rand 做同样的事情,为什么这些随机函数在 Mac 上的运行速度是否比 Windows 快?
编辑:为了澄清,mersenne 指的是 std::mt19937_64 被用于 Uniform_real_distribution 而不是 std::minstd_rand。
C++ 标准库中的所有发行版(包括uniform_real_distribution)都使用实现定义的算法。(这同样适用于std::rand,它遵循 C 标准的rand功能。)因此,在 C++ 标准库的不同实现中,这些分布之间的性能差异很自然。另请参阅此答案。
您可能想尝试测试 C++ 随机引擎(例如std::minstd_rand和std::mt19937)中是否存在性能差异,它们确实在 C++ 标准中指定了固定算法。为此,请直接在引擎中生成一个随机数,而不是通过任何 C++ 发行版,例如uniform_int_distribution或uniform_real_distribution。
我最初认为这是编译器优化省略了 Uniform_real_distribution 当它没有被存储/打印时因为变量没有被使用,因此可以省略,但是为什么编译器不对 std::rand[?] 做同样的事情?
我认为编译器可以进行这种优化,因为在实践中,C++ 标准库是作为编译器可用的 C++ 代码实现的,因此编译器可以根据需要对该代码执行某些优化。这与 with 不同std::rand,后者仅作为编译器无法实现的函数实现,限制了编译器可以执行的优化。