素数分段筛法指的是 the segmented sieve of EratoSieve, 将计算区间划分成若干个区间,
分别计算出每一个区间的素数, 一种分治算法的实现.
与传统筛法相比, 能更好的利用cpu的缓存, 大幅提升内存访问的性能( >3 倍),
还能减小对内存的需求.
举个例子, 计算100亿以内的素数, 我们把100亿均分成100等分,
每个区间长度为1亿, 然后计算每个长度为1亿的区间内素数.
问题是区间长度取多少整体筛法性能最好? 按我前面描述, 每个区间长度略小于cpu L1(或L2)大小比较合适,
这个具体数值依赖不同情况需具体测试。
(为了提高性能,甚至可以采用多级分段思想,每段大小和cpu的缓存大小接近,最新的算法采用这个思想,性能获得极大的提升)
当前的主流cpu单核心:
intel 一级数据缓存大小为32K. L2 256 - 2048(不同架构)
AMD 一级数据缓存大小为64K, L2 512 - 1024
我们以AMD cpu为例, 每个区间块最佳长度 = 64 * 1024 = 65536 bye,
如果我们采用bit压缩数据, 并且不考虑偶数, 那么计算长度扩大16倍数, 65536* 16 = 1048576
大量的测试表明实际, 最佳长度略小于1048576效果会比较好, 毕竟L2还需要存其他运行时数据
采用高级位压缩优化算法, 如果只存模30余1 7 11 13 17 19 23 29等, 这样压缩效率又可以提高一倍,
最佳长度约为200万, 算法也复杂了很多.
//sieve prime in [start, start + leng]
//start为偶数, 为加快算法只筛奇数.
//筛区间[start, start + leng],