我一直在寻找Sigmoid内核的Sigmoid函数和Sigmoid Prime实现,但我偶然发现偶然收到了对SO 的答复,其中使用了SO __fmul_rz和其他一些CUDA函数名称。因此,出于好奇,我用谷歌搜索了它们,发现它们是单精度函数,如下所示(注意:这些是针对4.1的)。
文档说这些是快速的近似值,因此直觉说它们跳过精度以提高计算速度?
以前我有:
float x = 1.f / (1.f + exp ( -1.f * input ) );
return x * ( 1.f - x );
Run Code Online (Sandbox Code Playgroud)
现在,我有:
float s = __fdividef( 1.f, (1.f + __expf(-1.f*input)));
return x = s * (1.f - s);
Run Code Online (Sandbox Code Playgroud)
我是否可以假设上述两个结果可能不同?
我是否可以假设上述两个结果可能不同?
您的假设是正确的。快速的数学内在函数将性能与某些特殊情况的精度和处理权衡。由用户决定这是否是可以接受的折衷。
在这些函数中,有些是标准函数的准确性较差但版本较快的函数,它们具有相同的名称
__(例如__sinf(x))。它们映射到较少的本地指令时速度更快。daccess-ods.un.org daccess-ods.un.org除了降低受影响功能的准确性外,它还可能在特殊情况下造成一些差异。
该文档还提供了一个实际的区别示例:
[...]对于2 126 <y <2 128,给出
__fdividef(x,y)的结果为零,而/操作员将正确的结果提供到表9所述的精度之内。同样,对于2 126 <y <2 128,如果x为无穷大,__fdividef(x,y)传递aNaN(作为无穷大乘以零的结果),而/运算符返回无穷大。
对于__expf(x),最大ULP错误范围被声明为,2 + floor(abs(1.16 * x))而符合IEEE规范expf的最大ULP错误范围为2。