#random #rand #no-std

no-std romu

使用 Romu 算法的伪随机数生成器

9 个版本 (5 个重大更改)

0.6.0 2024 年 3 月 23 日
0.5.1 2021 年 12 月 3 日
0.4.1 2021 年 12 月 1 日
0.3.0 2021 年 11 月 30 日
0.1.2 2021 年 11 月 28 日

#165 in 算法

Download history 14/week @ 2024-03-09 2/week @ 2024-03-16 141/week @ 2024-03-23 24/week @ 2024-03-30 2/week @ 2024-04-06

每月 386 次下载
用于 vk-alloc

Apache-2.0

100KB
2K SLoC

romu

Documentation Crates.io License: Apache 2.0

这是一个使用 Romu 算法为 Rust 编程语言编写的伪随机数生成器。

此伪随机数生成器(PRNG)不适用于加密目的。此软件包仅实现了原始作者推荐的 64 位 "RomuTrio" 生成器。

非线性随机数生成器

Romu 是一个非线性随机数生成器。这意味着周期是概率性的,基于种子。所需的周期越长,实际周期“太小”的可能性就越高。

以下公式由作者提供

    P(|cycle contains x<= 2^k|) = 2^k-s+7
        k is size of random numbers needed + 1.
        s is the state size.

获得“太小”周期的示例概率

  • 当需要 2^62 个 64 位数字(32 EiB)时 -> 2^-122 概率
  • 当需要 2^39 个 64 位数字(4 TiB)时 -> 2^-146 概率
  • 当需要 2^36 个 64 位数字(512 GiB)时 -> 2^-149 概率

您可以在官方论文和原始作者的官方网站上了解更多关于 Romu 背后理论的信息。

播种

当用户调用生成器的 new()default() 函数时,实现尝试使用最佳可用随机性来源来播种生成器(以下顺序)

  1. 使用 getrandom 软件包从操作系统的优质随机性来源进行播种。必须激活 getrandom 功能。
  2. 使用标准库的功能创建低质量随机性种子(使用当前时间、线程 ID 和内存地址)。必须激活 std 功能。
  3. 使用内存地址作为非常低质量的随机性种子。如果操作系统支持地址空间布局随机化(ASLR),则此值应该相当“随机”。

强烈建议使用与 no_std 兼容的 getrandom 功能来获取高质量随机性种子。

用户可以始终使用用户提供的种子值创建/更新生成器。

如果使用 tls 功能,用户应该在创建第一个随机数之前调用 seed() 函数来初始化 TLS,因为 TLS 实例使用的是固定值。

SIMD

该包目前提供三个宽生成器,旨在加快大量随机数的生成。

  • Rng128 - 128位宽度的生成器。
  • Rng256 - 256位宽度的生成器。
  • Rng512 - 512位宽度的生成器。

回退功能不会生成自动向量化代码,并且仅用于更好地利用 CPU 缓冲区。使用 Rng128 在填充字节切片时(AMD Ryzen 9 5950X)会导致吞吐量提高。

bytes/Rng/1048576       time:   [75.418 us 75.578 us 75.751 us]
                        thrpt:  [12.892 GiB/s 12.921 GiB/s 12.949 GiB/s]
bytes/Rng128/1048576    time:   [57.103 us 57.384 us 57.711 us]
                        thrpt:  [16.921 GiB/s 17.018 GiB/s 17.102 GiB/s]

手写的 SSE2 生成器不会提高吞吐量,因为它们不能在一条指令中计算 64 位乘法,而是需要多个 32 位乘法,并且宽度不够补偿。

然而,AVX2 为 Rng256Rng512 提供了特殊的手写实现,这大大提高了吞吐量(AMD Ryzen 9 5950X)。

bytes/Rng/1048576       time:   [75.774 us 76.037 us 76.313 us]
                        thrpt:  [12.797 GiB/s 12.843 GiB/s 12.888 GiB/s]
bytes/Rng128/1048576    time:   [56.840 us 57.031 us 57.251 us]
                        thrpt:  [17.057 GiB/s 17.123 GiB/s 17.181 GiB/s]
bytes/Rng256/1048576    time:   [54.443 us 54.562 us 54.680 us]
                        thrpt:  [17.859 GiB/s 17.898 GiB/s 17.937 GiB/s]
bytes/Rng512/1048576    time:   [35.528 us 35.618 us 35.721 us]
                        thrpt:  [27.338 GiB/s 27.418 GiB/s 27.487 GiB/s]

夜间仅有的功能 unstable_simd 使用 core::simd 创建来实现 SIMD 生成器。

特性

该包与 no_std 兼容。

  • std - 如果未使用 getrandom 或返回错误,生成器将使用线程名称和当前实例时间来创建种子值。默认启用。
  • tls - 创建使用线程局部版本生成器的静态函数。默认启用。
  • getrandom - 使用 getrandom 包创建高随机性的种子。默认启用。
  • unstable_tls - 使用 Rust 夜间版的不稳定 thread_local 功能。大大提高了对线程局部函数的调用时间。
  • unstable_simd - 使用 Rust 夜间版不稳定 std::simd 包提供宽生成器的 SIMD 版本。

许可证

根据 Apache License,版本 2.0 许可,(LICENSEhttp://www.apache.org/licenses/LICENSE-2.0)。

贡献

除非你明确表示,否则任何有意提交以包含在你提交的工作中的贡献,根据 Apache-2.0 许可,没有其他条款或条件。

依赖

~210KB