【发布时间】:2016-02-17 13:10:56
【问题描述】:
我正在 cuda 中开发一个 nbody 模拟器。我想使用浮点类型来提高速度,但这使我的任务变得困难。我担心的是说我有一个向量 并且我想使用勾股定理计算它的大小。我必须对每个 10^40 的组件进行平方,在 32 位中这将是无穷大。因此,即使我取和的平方根时的最终结果在范围内,中间步骤也会溢出。我在 cuda 数学 API 中遇到了以下函数。 norm3df(x, y, z)。这会防止我正在谈论的中间步骤溢出吗?此外,我可能需要在主机和设备上使用此功能。行为是否相同?
【问题讨论】:
-
什么会阻止您自己测试它?它实际上是 20 行代码...
-
标准C/C++函数
hypot()以及CUDA的附加函数rhypot()、norm3d()和rnorm3d()的目的正是为了避免在中间计算。由于rhypot()、norm3d()和rnorm3d()不是标准C/C++ 库的一部分,您将无法在宿主代码中使用它们。您可能想建议您的主机编译器供应商将这些函数作为专有扩展添加。 -
@njuffa 可能可以作为答案。 FWIW 我使用
norm3df()测试了建议的测试用例,它给出了173205081561134792704.0的正确答案。如果不存在主机实现,我很好奇为什么该函数在头文件和文档中都被标记为__host__ __device__。我也很好奇norm3d如何避免中间溢出。它是否对double算法使用了某种扩展? -
我假设它是在硬件中实现的,以避免 GPU 上的溢出。我也想知道为什么它被标记为 host 因为我无法链接它。
-
正如之前在另一个线程(此处或 NVIDIA 论坛)中讨论的那样,CUDA 头文件中似乎有一些函数被错误地标记为
__host__ __device__,可能是由于剪切和粘贴。我没有尝试在主机代码中调用norm3d(),但我认为不存在主机版本。防止中间溢出/下溢的技术是重新调整操作数以及使用实际计算的巧妙转换。不需要更高的中间结果精度。详情见math_functions.h、math_functions_dbl_ptx3.h的CUDA 6.5版本中的源码
标签: c++ cuda floating-point