【发布时间】:2011-03-08 17:14:16
【问题描述】:
根据链接:http://en.wikipedia.org/wiki/Sieve_of_Sundaram,生成最多 n 个素数列表的“sundaram 筛子”的运行时间为 O(n*log(n))。这个算法比“阿特金筛子”更好吗?如果能详细说明一下它是如何工作的?
【问题讨论】:
-
更好是什么意思?实践上好还是理论上好?
-
阿特金、埃拉托色尼、桑达拉姆……按这个顺序。
-
@st0le,您能支持将阿特金筛 (SoA) 放在首位吗?我有done research for this answer 说,SoA 仅在非常有限的特定情况下击败了最大优化的车轮分解埃拉托色尼筛 (SoE),如果有的话,也只有很小的差距。 Atkin 和 Bernstein 的研究存在缺陷,他们将参考 SoE 实现限制为仅与 SoA 固有的轮子分解级别相同,并且通过对 SoE 使用 4 KB 的缓冲区大小和对 SoA 使用 8 KB 的缓冲区大小破坏了它们的时序比较。
-
续:Atkin 筛和 Sundaram 筛的最大问题是高效的多重处理,因为它们有越来越多的序列,直到筛分范围的平方根,需要重新开始以不断增加的计算成本为每个新段页面计算地址。埃拉托色尼筛法的序列比率要低得多,仅基于基素数到范围的平方根,其密度随着范围的增加而降低。这也是为什么 Daniel Bernstein 的“primegen”没有随着范围的增加而显示经验 O(n) 性能的原因。
-
@Gordon:检查source code of primegen 表明,Dan Bernstein 为他的 Atkin 实现提供了一个筛缓冲区,该缓冲区是他用于 Eratosthenes 箔的筛缓冲区的 四倍 ( 2048 * 16 单位与 1001 * 8 单位)。此外,他的实现方法不能与现代内存缓存系统很好地交互。在这个老化的 Lynnfield 上,MinGW 构建的
primespeed在 0.68 秒内将素数计数到 10^9,eratspeed需要 0.70(重定向到文件!)。即使在 C# 中,我也可以通过仅赔率的 SoE 击败它,而无需使用 C/C++ 或 mod 30 轮。