首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么使用`std::uniform_real_distribution`是合适的?

为什么使用`std::uniform_real_distribution`是合适的?
EN

Stack Overflow用户
提问于 2022-02-12 06:22:39
回答 2查看 188关注 0票数 0

我在写大都会蒙特卡罗模拟代码。由于模拟时间很长,我想认真考虑一下在[0, 1]中生成随机数的性能。

因此,我决定通过以下代码检查两个方法的性能:

代码语言:javascript
运行
复制
#include <cfloat>
#include <chrono>
#include <iostream>
#include <random>

int main()
{
    constexpr auto Ntry = 5000000;

    std::mt19937 mt(123);
    std::uniform_real_distribution<double> dist(0.0, std::nextafter(1.0, DBL_MAX));
    double test1, test2;

    // method 1
    auto start1 = std::chrono::system_clock::now();
    for (int i=0; i<Ntry; i++) {
        test1 = dist(mt);
    }
    auto end1 = std::chrono::system_clock::now();
    auto elapsed1 = std::chrono::duration_cast<std::chrono::microseconds>(end1-start1).count();
    std::cout << elapsed1 << std::endl;

    // method 2
    auto start2 = std::chrono::system_clock::now();
    for (int i=0; i<Ntry; i++) {
        test2 = 1.0*mt() / mt.max();
    }
    auto end2 = std::chrono::system_clock::now();
    auto elapsed2 = std::chrono::duration_cast<std::chrono::microseconds>(end2-start2).count();
    std::cout << elapsed2 << std::endl;
}

结果是

  • 295489微秒用于方法1
  • 79884微秒用于方法2

据我所知,有许多帖子推荐使用std::uniform_real_distribution。但是从性能上看,使用后者是很有诱惑力的,正如这个结果所示。

你能告诉我使用std::uniform_real_distribution有什么意义吗?使用1.0*mt() / mt.max()的缺点是什么?在目前的情况下,是否可以使用1.0*mt() / mt.max()来代替?

编辑:

我用g++-11 test.cpp编译了这段代码。当我使用-O3标志编译时,结果在质量上是相同的(方法1大约是。速度慢1.8倍)。我想谈谈广泛使用的方法的优点.我确实关注表演的趋势,但具体的性能比较超出了我的范围。

EN

回答 2

Stack Overflow用户

发布于 2022-02-12 06:56:21

您使用标准随机库,因为正确地进行数值计算是非常困难的,而且您不想要证明和维护自己的随机库的负担。

例如,你的随机分布是错误的。std::mt19937生成32位整数,但是您需要一个具有53位意义的double (通常)。在范围[0, 1]中有一些值您永远不会从1.0*mt() / mt::max()中获得。

票数 4
EN

Stack Overflow用户

发布于 2022-02-12 06:59:11

您的测试方法存在缺陷。您不使用所生成的结果,因此聪明的优化器可能简单地跳过生成结果。

,你能告诉我使用std::uniform_real_distribution有什么意义吗?

  • ,线索就在名字里。它生成一个统一的distribution.
  • Furthermore,,它允许您指定希望分发的最小值和最大值。

使用1.0*mt() / mt.max()有什么缺点?

distribution.

  • It
  • 您不能指定一个最小值和一个最大值。
  • 它产生一个不那么均匀的
  • 会产生较少的随机性。

使用1.0*mt() / mt.max()是否可以接受?

在某些用例中,这是可以接受的。在其他一些情况下,这是不可接受的。在其他地方,这不重要。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71089479

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档