我正在为sigmoid内核寻找sigmoid函数和sigmoid prime实现,我偶然发现了upon a reply在SO中,它使用了__fmul_rz
和其他一些CUDA函数名。
所以我用好奇心搜索了它们,发现那些是单精度函数as shown here(注意:那些是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);
我是否正确地假设上面两个可能有不同的结果?
答案 0 :(得分:6)
我是否正确地假设上述两个可能会有不同的结果?
你的假设是正确的。快速数学内在函数交易性能的精度和处理一些特殊情况。由用户决定这是否是可接受的权衡。
CUDA C Programming Guide, Appendix D.2. Intrinsic functions:
在这些函数中,标准函数的某些函数的准确性较低但速度较快。它们的名称前缀为
__
(例如__sinf(x)
)。它们映射到较少的本机指令时速度更快。 [...]除了降低受影响功能的准确性之外,它还可能在特殊情况处理方面造成一些差异。
文档还提供了一个差异的实际例子:
[...] 2 126 < y< 2 128 ,
__fdividef(x,y)
传递的结果为零,而/
运算符将正确的结果传递到表9中所述的精度范围内。另外,对于2 126 < y< 2 128 ,如果x是无穷大,__fdividef(x,y)
提供NaN
(由于无穷大乘以零),而/
运算符返回无穷大。 / p>
对于__expf(x)
,最大ULP误差界限为2 + floor(abs(1.16 * x))
,而IEEE兼容expf
的最大ULP误差界限为2.