1

所以,我想在 GPU 上划分一些 32 位无符号整数,我不在乎得到一个精确的结果。事实上,让我们宽容一点,假设我愿意接受高达 2 的乘法误差因子,即如果 q = x/y 我愿意接受介于 0.5*q 和 2*q 之间的任何值。

我还没有测量任何东西,但在我看来,这样的东西(CUDA 代码)应该很有用:

__device__ unsigned cheap_approximate_division(unsigned dividend, unsigned divisor)
{
    return 1u << (__clz(dividend) - __clz(divisor));
}

它使用“查找第一个(位)集”整数内在函数作为廉价的以 2 为底的对数函数。

注意:我可以使这个非 32 位特定,但我必须使用模板使代码复杂化,__clz()使用模板函数包装以使用__clzl()等等__clzll()

问题:

  • 就时钟周期而言,这种近似除法是否有更好的方法?也许有稍微不同的约束?
  • 如果我想要更好的准确性,我应该使用整数还是应该只使用浮点算术?
4

1 回答 1

6

通过浮点运算可以为您提供更精确的结果,在大多数架构上的指令数略低,并且可能会提高吞吐量:

__device__ unsigned cheap_approximate_division(unsigned dividend, unsigned divisor)
{
   return (unsigned)(__fdividef(dividend, divisor) /*+0.5f*/ );
}

注释中的+0.5f应表明您还可以将 float->int 转换转换为适当的舍入,除了更高的能耗之外,基本上没有任何成本(它将 anfmul转换为fmad常量,常量直接来自常量缓存)。不过,四舍五入会使您远离确切的整数结果。

于 2017-03-01T15:57:36.193 回答