【问题标题】:Faster than rand()?比 rand() 快?
【发布时间】:2014-12-01 23:07:25
【问题描述】:

我正在研究一种算法,该算法需要尽可能快地生成数百万个数字。实际上我发现我的算法的 rand() 函数占用了 75% 的处理时间。

所以我正在寻找更快的东西。而且我根本不需要很大的范围。 (我只需要1000以下的整数)

你知道我可以用什么吗?

谢谢!

编辑:

我使用这个数字来洗牌少于 1000 个实体的组。

我发现了更多关于“快速兰特”的信息。还有 SSE 版本,速度更快,一次生成 4 个数字。

https://software.intel.com/en-us/articles/fast-random-number-generator-on-the-intel-pentiumr-4-processor/

【问题讨论】:

  • 3 秒的 75% 不算多。通常,rand() 非常快。您的代码需要多长时间才能创建 100 万个数字?
  • 不要将 75% 视为“慢”。毕竟,即使它在一纳秒内运行,something 也会占用 100% 的时间。如果程序除了生成随机数之外什么都不做,你会认为这会占用大部分时间。但是,如果您希望它更快,它确实会告诉您在哪里查看。
  • 我并不是说它“慢”,但如果我想改进我的算法,这可能是我应该开始的地方。
  • 我总是要问 - 你是从gprof 那里得到的吗?如果是这样,请不要相信,因为gprof 会忽略 I/O 之类的阻塞时间,以及在非 pg 编译库中花费的任何时间。如果你在某处写下这些数字,那很可能是真正的耗时的。 I use this method.
  • 你的“随机”数字需要有多“随机”?如果您在基于 Linux/glibc 的系统上,您的问题是 rand 实际上是根据 random 实现的,这是一个相当高质量(因此很慢)的 PRNG。像纯 LCG 这样的低质量的应该快得多,但可能有足够糟糕的统计属性,使它们不适合您的应用程序。

标签: c random


【解决方案1】:

Mersenne Twister 算法是一个相当快速但平衡的伪随机数生成器。

这是一个示例实现:http://fmg-www.cs.ucla.edu/geoff/mtwist.html

【讨论】:

  • 在大多数系统中,rand() 是一个伪随机数生成器。我想知道他的实现实际上有多慢。
  • 我猜他们不会更改默认实现,因为它会破坏预播种软件...
  • 现代 mersenne Twisters 与其同等排名的替代品相比确实没有那么快。
【解决方案2】:

在大多数系统中,rand() 是一个伪随机数生成器。所以代码应该只是几个移位 + 位或运算,并且能够在典型的 PC 上每秒产生数百万个数字。你没有说你得到了什么,你的硬件是什么,或者你正在使用哪个 C 库,所以很难看出你的实现为什么“慢”。

也许您可以尝试重用位:取最低十位(= 1024 个值),模 1000 得到您想要的数字范围。然后移位,当位用完时,再次调用rand() 以获取更多位。

【讨论】:

  • 我不确定这是否一定是个好主意,重复使用位可能无法保证他正在使用的最可能的线性全等方法的周期。
  • 如果您正在寻找高性能,模运算不是一个好主意。
【解决方案3】:
static unsigned int g_seed;

// Used to seed the generator.           
inline void fast_srand(int seed) {
    g_seed = seed;
}

// Compute a pseudorandom integer.
// Output value in range [0, 32767]
inline int fast_rand(void) {
    g_seed = (214013*g_seed+2531011);
    return (g_seed>>16)&0x7FFF;
}

【讨论】:

  • 您从哪里得知这比 Kevin 的机器所拥有的 rand() 实现更快?
  • 我刚刚测试过:1 亿个数字需要 1.2 秒,rand() 需要 5 秒。我必须检查它是否真的是随机的,但谢谢!
  • 它比 rand() 快一点。有一些极端情况,但没什么大不了的。 @JensGustedt 和我的荣幸 kevinP
  • 它使我的算法的时间减少了 35%,结果相似。我想我会将您的 fastrand 与 @Aaron Digulla 的答案结合起来,以进一步改进它。
  • @KevinP:这是一个简单的Linear Congruential Generator,使用与 Microsoft rand() 实现相同的参数。它速度快,但随机性不高。
【解决方案4】:

如果您使用的是 Intel Ivy Bridge 处理器,您可以使用 RDRAND 指令将随机数生成卸载到硬件上。

这个stack overflow article 谈论 RDRAND 的吞吐量。

您还可以确定处理器是否支持 RDRAND 并使用硬件卸载或回退到软件实现。

【讨论】:

    猜你喜欢
    • 2021-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-07
    • 2019-01-30
    相关资源
    最近更新 更多