cuda快速近似函数:代价是什么



我正在为sigmoid内核寻找sigmoid函数和sigmoid素数实现,无意中在SO中发现了一个使用__fmul_rz和其他一些CUDA函数名的回复。出于好奇,我在谷歌上搜索了一下,发现这些都是单精度函数,如下所示(注:这些是4.1的函数)

文件说这些是快速近似所以,直觉说它们跳过了精度,以便使计算更快?

以前我有:

float x = 1.f / (1.f + exp ( -1.f * input ) );
return x * ( 1.f - x );

而现在,我有:

float s = __fdividef( 1.f, (1.f + __expf(-1.f*input)));
return x = s * (1.f - s);

我认为上面的两个可能有不同的结果,这是对的吗?

我认为以上两种情况可能会产生不同的结果,这是对的吗?

你的假设是正确的。快速数学本质以性能换取精度和对某些特殊情况的处理。这取决于用户来决定这是否是一个可接受的折衷方案。

CUDA C编程指南,附录D.2。内部函数:

在这些函数中,有一些标准函数的精度较低但速度较快的版本。它们具有相同的名称,前缀为__(如__sinf(x))。它们的速度更快,因为它们映射到更少的本机指令。[…]除了降低受影响功能的准确性外,还可能导致特殊情况处理的一些差异。

文档还提供了一个实际的差异示例:

[…]对于2126<y<2128__fdividef(x,y)传递的结果为零,而/运算符传递的正确结果在表9中规定的精度范围内。对于2126<y<2128,如果x是无穷大,则__fdividef(x,y)传递NaN(作为无穷大乘以零的结果),而/运算符返回无穷大。

对于__expf(x),最大ULP误差界被声明为2 + floor(abs(1.16 * x)),而符合IEEE的expf具有2的最大ULP错误界。

最新更新