素数

primecount是一个命令行程序C/C++库它计算x≤10以下的素数31使用高度优化组合运算的实现素数计数算法.
素数包括所有重要的组合素数计算算法的实现,所有这些算法都是用OpenMPprimecount包含有史以来第一个开源的Deleglise-Rivat算法和Xavier-Gourdon算法的实现新型负载平衡器它在所有实现中共享,可扩展到数百个CPU核心。素数已被用来计算数个素数函数世界纪录.
安装
primecount命令行程序可以在一些包管理器中使用libprimecount开发
或libprimecount开发
.
窗户: |
Wingent安装primecount |
macOS系统: |
brew tap kimwalisch/primecount
brew安装primecount |
Arch Linux系统: |
sudo pacman-S素数 |
软呢帽: |
sudo dnf安装primecount |
开放SUSE: |
sudo zypper安装primecount |
生成说明
你需要安装一个C++编译器和CMake。理想情况下,primecount应该使用GCC或Clang进行编译,因为这些编译器同时支持OpenMP(多线程库)和128位整数。
cmake公司.make-j
sudo make安装
使用示例
#数数10^14以下的素数素数1e14#在计算期间打印进度和状态信息素数1e20——状态#用梅塞尔算法计算素数素数2**32——梅塞尔#用4个线程求10^14素数素数1e14——第n素数——线程数=4——时间
命令行选项
使用prime-Count算法时,使用prime-Count算法勒让德公式
——用莱默公式计算素数——用拉格丽亚斯·米勒·奥德莱兹科
-m计算素数,--梅塞尔计数素数用梅塞尔公式
——Li用对数积分
——Li逆近似π(x)用Li ^-1(x)
-n,--n素数计算第n素数
-p,--素数使用埃拉托斯泰尼的筛网计算素数
——phi<x><A>phi(x,A)计算不可被任何第一个a素数整除的<=x
--Ri近似pi(x)使用Riemann R
-Ri逆近似使用Ri^-1(x)
-s,--status[=NUM]显示计算进度1%、2%、3%,…
设置小数点后的位数:-s1打印99.9%
——测试运行各种正确性测试并退出
——time打印以秒为单位的时间
-t,--threads=NUM设置线程数,1<=NUM<=CPU核心。
默认情况下,primecount使用所有可用的CPU内核。
-v,--版本打印版本和许可证信息
-h,--help打印此帮助菜单
高级选项
Deleglise Rivat算法的高级选项:
-a,---普通调整函数
离开特殊调整集
——普通计算
y离开特殊调整集
——易计算
S2离开特殊的α集
——易计算α2
x为Xavier-Gourdon算法留下
——alpha-y=NUM Set tuning factor:y=x^(1/3)*alpha
——alpha-z=NUM Set tuning factor:z=y*alpha
——AC计算A+C公式
——B计算B公式
——D计算D公式
——Phi0计算φ0公式
——西格玛计算7西格玛公式
基准
十 |
质数 |
勒让德 |
梅塞尔 |
拉加里亚斯 米勒 奥德莱兹科 |
德莱斯利 里瓦 |
古尔登 |
1010 |
455052511号 |
0.02秒 |
0.01秒 |
0.00秒 |
0.00秒 |
0.00秒 |
1011 |
4118054813号 |
0.02秒 |
0.01秒 |
0.01秒 |
0.01秒 |
0.01秒 |
1012 |
37607912018号 |
0.09秒 |
0.05秒 |
0.02秒 |
0.01秒 |
0.01秒 |
1013 |
346065536839号 |
0.39秒 |
0.19秒 |
0.05秒 |
0.03秒 |
0.02秒 |
1014 |
3204941750802 |
2.24秒 |
0.96秒 |
0.16秒 |
0.12秒 |
0.07秒 |
1015 |
29844570422669 |
14.58秒 |
5.96秒 |
0.63秒 |
0.38秒 |
0.21秒 |
1016 |
279238341033925 |
111.81秒 |
42.91秒 |
2.83秒 |
1.59秒 |
0.76秒 |
1017 |
2623557157654233 |
938.07秒 |
352.39秒 |
12.70秒 |
4.72秒 |
2.83秒 |
1018 |
24739954287740860 |
8268.52秒 |
3144.72秒 |
57.31秒 |
18.96秒 |
10.77秒 |
1019 |
234057667276344607 |
南 |
南 |
南 |
89.02秒 |
45.56秒 |
1020 |
22208119602560918840 |
南 |
南 |
南 |
385.61秒 |
188.70秒 |
1021 |
2117269486018731928 |
南 |
南 |
南 |
1652.66秒 |
800.57秒 |
1022 |
201467286689315906290 |
南 |
南 |
南 |
7355.69秒 |
3260.95秒 |
上述基准测试是在2019年英特尔至强白金8275CL CPU
的系统上运行的,使用8个CPU核(16个线程),时钟频率为3.00GHz。请注意,Jan Büthe在[11]他计算了π(1025)使用分析素数计数函数算法,在40000个CPU核心小时内。
Büthe还提到,通过使用zeta函数的额外零,运行时间有可能减少到4000个CPU核心小时。但是使用primecount和Xavier-Gourdon的算法pi(1025)在AMD Ryzen 3950X CPU上,仅需460个CPU核心小时即可计算!
性能提示
如果您有一个x64cpu,并且使用Linux发行版的包管理器安装了primecount,那么POPCNT公司
指令已被禁用,以确保primecount在非常旧的cpu上工作。不幸的是,这会使性能降低30%。另一方面,如果从源代码编译primecountPOPCNT公司
默认情况下将启用指令。使用Clang编译器和-三月=本地
选项。
CXX=clang++cxflags="-本土三月"cmake公司.制造商-j
默认情况下,primecount可以很好地扩展到1020对于更大的值,primecount的大量内存占用导致了很多TLB(翻译查询缓冲区)缓存未命中会显著降低primecount的性能。
幸运的是Linux内核允许启用巨大的透明页面因此,大内存分配将自动使用巨大的
页而不是普通页来完成,这大大减少了
TLB缓存未命中的数量。
#在下次重新启动之前启用透明的大页面sudo bash-c'echo always>/sys/kernel/mm/transparent_hugepage/enabled'
算法
直到19世纪早期,已知的最有效的素数计算方法是埃拉托什尼筛,其运行时间为
操作。对这个界的第一个改进是勒让德公式
(1830),它使用包含排除原理来计算
x以下的素数,而不必枚举单个素数
操作和使用
空间。1870年,E.D.F.Meisel通过设置
加上修正项
迈萨公式的运行时间
操作和使用
空间。1959年,D.H.Lehmer扩展了Meisel的公式,并稍微改进了运行时间
运营和
空间。1985年J.C.Lagarias,V.S.Miller和A.M.Odlyzko发表了一个基于Meissel公式的新的
算法,该算法的运行时复杂度较低
只使用
空间。
primecount的Legendre、meisel和Lehmer实现基于Hans Riesel的书[5]它的Lagarias-Miller-Odlyzko和Deleglise-Rivat的实现基于Tomás Oliveira的论文[9]而Xavier-Gourdon算法的实现是基于Xavier-Gourdon的论文[7]素数对特殊叶公式的实现不同于迄今为止任何组合素数论文中描述的算法。primecount使用线性计数器数组与POPCNT指令相结合,这样缓存效率更高,速度更快,而不是使用二进制索引树进行计数。这个特殊叶子.md文档包含更多信息。
快速n次素数计算
已知计算第n个素数最有效的方法是素数计数函数和素数筛的组合。其思想是接近第n个素数(例如,使用反对数积分
或者逆Riemann R函数
)然后用素数计数函数计算素数。一旦完成了这一步,就开始从那里开始筛分(例如,使用埃拉托什尼的分段筛),直到找到实际的第n个质数。作者已经实现了素数::第n个素数(n)
这样(选项:--第n素数
),它在
操作使用
空间。
美国石油学会
包括<primecount.h>
头来使用primecount的capi。
primecount的capi返回的所有函数-1
如果发生
错误,并将相应的错误消息打印到标准错误流中。
#包括 <素数。h>#包括 <标准偏差>
内景 主要的()
{国际64皮克斯=素数(1000);印刷品("1000以下的质数=%ld公司\n",像素);返回 0;
}
C++API
包括<primecount.hpp>
头来使用primecount的C++API。
primecount的C++API的所有函数都抛出一个素数计数错误
异常(源于std::异常
)以防发生错误。
#包括 <素数.hpp>#包括 <流>
内景 主要的()
{国际64皮克斯=素数::π(1000);
标准::cout<<"1000以下的质数="<<pix<<std::endl;返回 0;
}
其他语言的绑定
primesieve本机支持C和C++并具有以下绑定:
非常感谢这些绑定的开发人员!