首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >std::uniform_real_distribution与std::uniform_int_distribution性能

std::uniform_real_distribution与std::uniform_int_distribution性能
EN

Stack Overflow用户
提问于 2020-07-07 20:08:59
回答 1查看 950关注 0票数 4

在我的一个应用程序中,我遇到了性能下降的问题,我将其定位于随机数据的生成。我编写了一个基本相同的简单基准:

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

std::mt19937 random_engine{std::random_device()()};

// Generate one million random numbers
template <typename T, typename Distribution>
std::vector<T> generate_random(Distribution distribution) {
  std::vector<T> data(1000000);

  std::generate_n(data.begin(), 1000000, [&]() {
    return static_cast<T>(distribution(random_engine));
  });
  return data;
}

template <typename T>
std::vector<T> create_data() {
  if constexpr (std::is_same_v<T, float>)
    return generate_random<float>(
        std::uniform_real_distribution<float>(-127.0f, 127.0f));
  if constexpr (std::is_same_v<T, int8_t>)
    return generate_random<int8_t>(
        std::uniform_int_distribution<int32_t>(-127, 127));
}

int main() {
  auto start = std::chrono::system_clock::now();
  auto float_data = create_data<float>();
  std::cout << "Time (float): " << (std::chrono::system_clock::now() - start).count()
            << '\n';

  start = std::chrono::system_clock::now();
  auto int8_data = create_data<int8_t>();
  std::cout << "Time (int8): " << (std::chrono::system_clock::now() - start).count()
            << '\n';

  return 0;
}

在我的机器上,这个输出:

代码语言:javascript
复制
〉g++ -v
...
Apple clang version 11.0.3 (clang-1103.0.32.29)
Target: x86_64-apple-darwin19.5.0
...

〉g++ tmp.cpp -std=c++17 -O3 && ./a.out
Time (float): 68033
Time (int8): 172771

为什么来自实际分布的抽样比从int分布中取样所花费的时间更短?

更新

libc++和libstdc++表现出完全相反的行为。我仍在研究实现方面的差异。见libc++ vs. libstdc++

EN

回答 1

Stack Overflow用户

发布于 2020-07-07 23:26:02

回想一下随机数分布的C++标准不指定特定的算法。,包括uniform_int_distributionuniform_real_distribution

因此,您必须研究C++标准库的特定实现(这对于Clang编译器来说通常很容易,因为它倾向于使用开源库libstdc++)。但是,在间隔[a,b]中生成浮点数(如float)与在同一间隔内生成整数之间存在差异:

  • 浮点数字:在大多数实际情况下,给定间隔中的浮点数比该区间中的整数要多。实现可以在一个范围内生成“统一”伪随机浮点数,方法是在[0,1]中生成“统一”伪随机浮点数(例如使用generate_canonical,其规范到目前为止不幸存在缺陷),然后缩放该数字以适应uniform_real_distribution给出的范围。这可能包括使用浮点乘法、除法或其他操作.
  • 整数:在一个范围内生成整数通常涉及生成足够多的随机比特来适应这个范围,然后使用模缩减或拒绝抽样(而后者是无偏的)。该过程将倾向于不使用浮点操作(与整数运算相比,浮点运算相对较慢),这可以解释您发现的性能差异。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62783133

复制
相关文章

相似问题

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