随机数生成器的性能因平台而异

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

我已经测试了使用std :: minstd_rand的std :: 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";

使用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";

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

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

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

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

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

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

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

所以

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毫秒的时间

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

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

编辑: 为了澄清起见,mersenne指的是std :: mt19937_64,而不是std :: minstd_rand,以表示Unified_real_distribution。

jiulongrushui 回答:随机数生成器的性能因平台而异

C ++标准库中的所有发行版(包括cmake_minimum_required(VERSION 3.12.1) project(my_library C) FILE(GLOB SOURCE_FILES src/*.c) add_library(my_library ${SOURCE_FILES}) target_include_directories(my_library PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $<INSTALL_INTERFACE:include>) set(OUTPUT_DIR "${CMAKE_BINARY_DIR}/output") set(INSTALL_DIR "${OUTPUT_DIR}/my_library") set(INSTALL_LIB_DIR "${INSTALL_DIR}/lib") set(INSTALL_INC_DIR "${INSTALL_DIR}/include") set(CMAKE_INSTALL_PREFIX "${INSTALL_DIR}") install(TARGETS my_library ARCHIVE DESTINATION lib) install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include" DESTINATION include) # I was hoping I could do,after setting the headers with the INSTALL_INTERFACE generator expression #install(TARGETS my_library ARCHIVE PUBLIC_HEADERS) )均使用实现定义的算法。 (同样适用于uniform_real_distribution,它遵循C标准的std::rand函数。)因此,很自然地,在C ++标准库的不同实现中,这些发行版之间会有性能差异。另请参见this answer

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


  

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

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

本文链接:https://www.f2er.com/3152645.html

大家都在问