GPU上的廉价近似整数除法

时间:2017-03-01 15:10:29

标签: cuda integer-division approximate

所以,我想在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));
}

它使用"find first (bit) set" integer intrinsic作为廉价的基数2对数函数。

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

问题:

  • 就时钟周期而言,是否有更好的近似分割方法?也许约束略有不同?
  • 如果我想要更高的准确度,我应该保持整数还是我应该通过浮点算术?

1 个答案:

答案 0 :(得分:5)

通过浮点运行可以获得更精确的结果,大多数架构的指令数略低,并且可能具有更高的吞吐量:

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

评论中的+0.5f表示您还可以将float-&gt; int转换转换为适当的舍入,除了更高的能耗之外基本上没有任何成本(它将fmul转换为{ {1}}常量直接来自常量缓存)。舍入会使您远离确切的整数结果。