是否有一种可移植的方法来使用 OpenACC 生成随机数?我知道可以直接使用 cuRand,但我仅限于 Nvidia GPU。 另一种选择似乎是在主机上生成数字,然后将它们移动到设备,但这似乎不是性能方面的最佳解决方案。
有更好的方法吗?
最佳答案
并行使用随机数生成器本质上是一项棘手的操作。 RNG 带有一个状态变量,该变量需要每个并行线程私有(private)。使用系统的“rand”是有问题的,因为它使用全局状态变量,当在并行上下文中使用时,该变量会给出未定义的行为(竞争条件)。应使用更多并行 RNG,例如“rand_r”和 Boost 的 PRNG。
第二个问题是 RNG 并不总是可移植的。不同的平台可能以不同的方式实现“rand”。正如您所确定的,NVIDIA 设备上没有可用的“rand”调用,您需要使用 cuRAND 调用。
OpenACC 旨在帮助以与平台无关的方式利用代码中的并行性。因此,诸如并行 RNG 之类的平台特定操作很难在标准本身内定义。也许可以做点什么,特别是对于像 PRNG 这样有用的东西,我建议您联系 OpenACC 标准委员会请求这种支持 (feedback_at_openacc_dot_org)。
现在唯一真正可移植的方法是编写您自己的并行 RNG 并将其作为代码的一部分。顺便说一句,我没有写一个 OpenACC 示例,而且有点不知所措,所以不知道我是否有时间,但会尽力将一个示例放在一起。
我确实编写了 Mersenne Twister 算法的 CUDA C 版本,作为我大约 8 年前写的一篇文章的一部分,该文章可能会有所帮助(尽管它早于 OpenACC)。它在文章开头使用了 PGI 加速器模型,中间使用了 CUDA Fortran,因此不必太担心内容,只需 MT 源即可。
https://www.pgroup.com/blogs/posts/tune-gpu-monte-carlo.htm
源码包:https://www.pgroup.com/lit/samples/pginsider/pgi_mc_example.tar.gz
关于c++ - 使用 OpenACC 生成可移植随机数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55080319/