我一直在尝试在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;
}
还有改进的余地吗?现在我的程序花了大部分时间在这个功能上。
答案 0 :(得分:2)
我的第一个想法是对它进行矢量化,潜在的速度可达~1.6倍。每个循环使用5次乘法,而原始使用2次乘法,但是对于足够大的N,使用大约四分之一的循环次数。将所有double
转换为long
,并交换{ {1}} fmod
s可能会提供一些加速,具体取决于所使用的GPU和其他内容。
%
编辑:我很确定它现在有效。
答案 1 :(得分:0)
nt = log2(n);
的循环可以替换为
if (n & 1) ...; n >>= 1;
r = 16;
,fmod(r * r,ak)vs fmod(16 * r,ak)可以很容易地延迟,只计算每第N次迭代的模数 - 循环展开?