ice*_*man 4 c primes sieve-of-eratosthenes
有关如何让这个程序工作n = 1万亿(除了升级/购买新计算机)的任何建议?
错误如下:构建后,正在执行的程序(命令行样式输出窗口弹出)然后快速关闭,我得到以下错误"ProjectPrimes.exe已停止工作(Windows正在寻找解决方案这个问题."我怀疑这与内存问题有关,因为我第一次遇到n = 2000万,但那是在我选择malloc /释放'筛'阵列之前(即我的'筛'阵列是大阵列)尺寸nx 1,每个元素由1或0组成.
该程序需要大约35秒才能完成前3亿个整数(16,252,325个素数),所以没关系,但没什么了不起的.正如我所提到的,目标是能够产生低于1万亿的质数,所以我还有很长的路要走......
如果相关,这是我的机器规格(如果在这台机器上目标恰好是不合理的):2.40ghz i5,4GB RAM,64位Windows 7.
方法概述,对于那些不熟悉的人:我们使用Sienda of Sundaram方法.在没有进入证明的情况下,我们首先使用筛选函数消除整数"n"以下的所有奇数非素数:[2*(i + j + 2*i*j)+1 | i < - [1..n/2],j < - [i..an优化上限]].然后我们交掉偶数(当然不包括两个).这让我们留下了素数.
为什么prime函数返回(指向包含数组的指针)n下面的完整素数集?那么,目标是能够识别(i)n以下的素数以及(ii)列出n以下的素数.这也是为什么我选择传递一个指针,用于将n下面的素数计数作为参数.
这是不那么令人兴奋的"主要"功能:
int main() {
long ceiling = 300*1000*1000;
long *numPrimes;
long *primes;
primes = primesToSS(ceiling+1, numPrimes);
printf("\n\nThere are %d primes below %d.\n\n",*numPrimes,ceiling);
free(primes);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是肉:
//n represents the ceiling, i.e., the integer below which we will generate primes
//cnt* is a pointer which will point the number of primes below n
long* primesToSS( long n, long* cnt ) {
//initialize sieve by setting all elements equal to 1 (except for 0 and 1)
long *sieve = malloc(n*sizeof(long));
initArray(sieve, n, 1);
sieve[0] = 0; sieve[1] = 0;
//eliminate all odd composite numbers
for (int i = 1; i <= n/2; ++i)
for (int j = i; j <= (n-2*i)/(2*(2*i+1)); ++j)
sieve[ 2*(i+j+2*i*j)+1 ] = 0;
//eliminate all even numbers greater than two
//and count total number of primes below n
long numPrimes = 1;
for (int i = 3; i < n; ++i) {
if (i % 2 == 0) sieve[i] = 0;
numPrimes += sieve[i];
}
*cnt = numPrimes;
//create array of primes
long *primes = malloc(numPrimes*sizeof(int));
long counter = 0;
for (int i = 0; i < n; ++i) {
if (sieve[i] == 1) {
primes[counter] = i;
counter++; }
}
free(sieve);
return primes;
}
void initArray( int* arr, int len, int n ) {
for( int i = 0; i < len; ++i) arr[i] = n; }
Run Code Online (Sandbox Code Playgroud)
让我们做一些观察:
打包数量为16个数字/字节(你应该做的最基本的设置),你需要~58 GiB的RAM.但是,没有必要为整个范围分配.只需分配几亿到几十亿的较小范围(尝试改变最高性能的数量),最多可以转化为几百MiB,然后使用不到100万的素数列表筛选范围.
此步骤可以并行完成 - 您只需要共享少于100万的素数列表.
顺便说一下,这种技术称为分段筛.