在OpenCL中快速实现二进制求幂

时间:2014-01-20 23:24:59

标签: c opencl pow exponentiation modular-arithmetic

我一直在尝试在OpenCL中设计一个快速二进制求幂实现。我目前的实现与this book about pi中的实现非常相似。

// Returns 16^n mod ak
inline double expm (long n, double ak)
{
    double r = 16.0;
    long nt;

    if (ak == 1) return 0.;
    if (n == 0) return 1;
    if (n == 1) return fmod(16.0, ak);

    for (nt=1; nt <= n; nt <<=1);

    nt >>= 2;

    do
    {
        r = fmod(r*r, ak);
        if ((n & nt) != 0)
            r = fmod(16.0*r, ak);
        nt >>= 1;
    } while (nt != 0);
    return r;
}

还有改进的余地吗?现在我的程序花了大部分时间在这个功能上。

2 个答案:

答案 0 :(得分:2)

我的第一个想法是对它进行矢量化,潜在的速度可达~1.6倍。每个循环使用5次乘法,而原始使用2次乘法,但是对于足够大的N,使用大约四分之一的循环次数。将所有double转换为long,并交换{ {1}} fmod s可能会提供一些加速,具体取决于所使用的GPU和其他内容。

%

编辑:我很确定它现在有效。

答案 1 :(得分:0)

  • 提取nt = log2(n);的循环可以替换为  if (n & 1) ...; n >>= 1;
     在do-while循环中。
  • 鉴于最初 r = 16;,fmod(r * r,ak)vs fmod(16 * r,ak)可以很容易地延迟,只计算每第N次迭代的模数 - 循环展开?
  • 也为什么fmod?