我正在寻找一个快速模10算法,因为我需要加快我的程序,它做了许多模运算周期。
我已经检查了this page,它比较了一些替代品。据我正确理解,T3是所有中最快的。我的问题是,如何将x % y
看起来像使用T3技术?
为了简单起见,我在这里复制了T3技术,以防链接中断。
for (int x = 0; x < max; x++)
{
if (y > (threshold - 1))
{
y = 0; //reset
total += x;
}
y += 1;
}
关于评论,如果这不是真的快,然后定期国防部,我正在寻找至少2倍的模比使用%
。我已经看到了许多例子与使用2的权力,但由于10不是,我怎么才能让它工作?
编辑:
对于我的程序,假设我有2个循环,其中n=1 000 000
和m=1000
。
看起来像这样:
for (i = 1; i <= n; i++) {
D[(i%10)*m] = i;
for (j = 1; j <= m; j++) {
...
}
}
5条答案
按热度按时间vm0i2vca1#
以下是你可以编写的最快的模10函数:
下面是它编译后的样子:
注意缺少除法/求模指令,神秘的常量,使用最初用于复杂数组索引的指令等。不用说,编译器知道很多技巧,可以让你的程序尽可能快。你很少会在这样的任务中击败它。
o7jaxewo2#
你可能无法击败编译器。
调试版本
零售构建(在那里做一些忍者数学...)
zf9nrax13#
代码不是模的直接替代,它在那种情况下替代模 *。你可以通过类比来编写你自己的
mod
(对于a
,b
〉0):但它是否比
%
更快是非常值得怀疑的。zlwx9yxi4#
我遇到了这个讨论,而对于
uint64_t
,执行mod 10操作的最佳方法确实是通过在我的标准笔记本电脑上使用编译器。然而,对于我最近的ubuntu linux上的unt128_t
,对于例程:时间:
这与我使用
uint64_t
得到的结果非常不同。因此,可以期望在这里做一些聪明的事情(我敢打赌,在未来的gcc版本中,他们会实现以下技巧的某种形式)。我们可以利用规则,还有
为了生成代码,
这是以速度为基准
对于模10运算来说,这是一个很好的5倍加速。注意,10在这里并不是魔术,除了编译器可能对64位无符号整数的10特别聪明。类似的技巧可以用于整数除以10,我们注意到我们总是可以将数字x写成x = a 10 + b,其中a = x/10和b = x%10,然后我们可以再次研究x1*x2和x1+x2,以利用64位整数的快速版本推导出128位整数除法的类似规则。
在gcc中使用优化-O3编译到类似的5倍加速。
8cdiaqws5#
这将适用于大于机器字的(多字)值(但假设是二进制计算机...):
更新:通过一些额外的努力,你可以得到没有乘法的算法,并且 * 通过适当的优化 * 我们甚至可以得到内联的递归调用:
mod10_1的结果看起来没有穆尔/div,几乎没有分支: