4

我需要一个可重复的伪随机函数,从 [0,1] 中的浮点数到 [0,1] 中的浮点数。即给定一个 32 位 IEEE 浮点数,返回一个“不同”的浮点数(尽可能随机,给定 24 位尾数)。它必须是可重复的,所以保持大量的内部状态是不可能的。不幸的是,它只能使用 32 位 int 和单浮点数学(没有双精度,甚至没有 32x32=64 位乘法,尽管如果需要我可以模拟——基本上它需要在较旧的 CUDA 硬件上工作)。当然,在这些相当严格的限制范围内,随机性越好。有人有想法么?

(我经历过需要 64 位 int 数学的 Park-Miller,以及需要双精度数的 Park-Miller 的 CUDA 版本,具有大量内部状态的 Mersenne Twisters,以及其他一些不起作用的东西。 )

4

3 回答 3

3

NVIDIA CUDA Toolkit 包含一个名为CURAND的库,我相信它符合您的要求:它产生可重复的结果(假设您从相同的种子开始),适用于 GPU,支持 32 位浮点数和整数,并且应该适用于较旧的 GPU。它还支持多种伪随机和准随机生成算法和分布。

[注意:使用 C 库 rand() 函数的一个问题(除了它不在设备上的 CUDA 中运行)是在 Windows 上,rand() 只返回一个 16 位值,因此任何由除以 RAND_MAX 只有 16 个随机位的精度。更重要的是,在 linux/mac 上它返回一个 32 位的值,所以使用它的代码在数字上是不可移植的。]

于 2011-06-01T00:46:38.930 回答
3

最好我理解要求,哈希完成所需的功能。将浮点输入重新解释为整数,应用哈希函数产生一个近似均匀分布在 [0,2^32) 中的整数,然后将该整数乘以 2^-32 以将得到的整数转换回大致均匀的浮点数分布在 [0,1] 中。一种不需要乘法的合适散列函数是 Bob Jenkin 的 mix(),可以在这里找到:http ://www.burtleburtle.net/bob/hash/doobs.html 。

要将浮点数的位重新解释为整数,反之亦然,CUDA 中有两种选择。使用内在函数,或使用 C++ 风格的重新解释强制转换:

float f;
int i;
i = __float_as_int(f);
f = __int_as_float(i);
i = reinterpret_cast<int&>(f);
f = reinterpret_cast<float&>(i);

所以作为一个独立的函数,整个过程可能看起来像这样:

/* transform float in [0,1] into a different float in [0,1] */
float scramble_float (float f)
{
    unsigned int magic1 = 0x96f563ae; /* number of your choice */
    unsigned int magic2 = 0xb93c7563; /* number of your choice */
    unsigned int j;
    j = reinterpret_cast<unsigned int &>(f);
    mix (magic1, magic2, j);
    return 2.3283064365386963e-10f * j;
}
于 2011-06-02T07:34:17.117 回答
2

为什么不使用标准 C 库rand()函数并将结果除以RAND_MAX

#include <stdlib.h>
float randf (void)
{
     return rand() / (float) RAND_MAX;
}
于 2011-05-31T23:09:20.713 回答