Calculated pi with 487 billion digits by diskized GMP

cents2823 at yahoo.co.jp cents2823 at yahoo.co.jp
Fri Sep 1 05:06:31 CEST 2023


* { font-size: 13px; font-family: 'MS Pゴシック', sans-serif;}p, ul, ol, blockquote { margin: 0;}a { color: #0064c8; text-decoration: none;}a:hover { color: #0057af; text-decoration: underline;}a:active { color: #004c98;}
Hi,




I am making a program to calculate pi with gmp and Chudnovsky Algorithm. 




If the number of digits to calculate pi increases,




it takes using swap and takes a lot of time(*1) to calculate.




So I diskized(*2) some functions of gmp and calculated pi 487 billion digits.




It took about 10 days to calculate.




I also calculated pi with y-cruncher and checked the result of a match.




On the same PC, y-cruncher can calculate 1 trillion digits of pi in 32 hours. 




Why so fast!




Thanks!

Tsukamoto







(*1)




gmp and diskized large number multiplication time.




Large number multiplication time is most of pi calculation time. 




large number digit(a,b)  2.5*10^10 5*10^10  10^11  2*10^11   




gmp a*b time(sec)        803  2,060  7,069   27,041 




diskized a*b time(sec)     469  1,014  2,302   5,052 




test pc:




 cpu: i9-7940X 14 core 28 threads




 memory: 128GB




 os: ubuntu 20.04.6 LTS




 gcc: 10.0.1




 gmp: 6.2.1




 nvme SSD 1TB x 8, 2TB x 1

  




(*2) 




Diskized some gmp functions




mpz_mul -->    schon_mul: use Schonhage Strassen Algorithm




              and openmp parallel processing




mpf_div -->    recip: 1/b + schon_mul: (1/b)*a




mpf_sqrt_ui -->  sqrtr: sqrt(a) = (1/sqrt(a))*a

  

mpz_add -->    mpz_addf




mpz_sub -->    mpz_subf







Change of disk-related gmp functions




mpz_out_raw -->  mpz_out_raw_p(*3: c sorce)




mpz_inp_raw -->  mpz_inp_raw_p(*4: c sorce)







(*3) 




void mpz_out_raw_p(FILE **fp, mpz_t a)




{




// fp <-- a




// disk output format is different from gmp




// big endian --> little endian,




// byte size(32bit) --> lim size(64bit)







 long int insizeb = a->_mp_size;

  

 long int insizea = labs(insizeb);

  

 if(fwrite(&insizeb, 8, 1, *fp) < 1){

  

   printf("\nFailed to write:mpz_out_raw_p\n");

    

   abort();

    

 }

  

 if(insizea > 0){

  

   if(fwrite(a->_mp_d, 8, insizea, *fp) < (unsigned long int)insizea){

    

     printf("\nFailed to write:mpz_out_raw_p\n");

      

     abort();

      

   }

    

 }

  

}







(*4) 




void mpz_inp_raw_p(mpz_t a, FILE **fp)




{




// a <-- fp




//







 long int insizea, insizeb;

  

 fread(&insizeb, 8, 1, *fp);

  

 insizea = labs(insizeb);

  

 if(insizea > 0){

  

   mpz_set_ui(a, 1);

    

   mpz_mul_2exp(a, a, (insizea - 1) * 64);

    

   fread(a->_mp_d, 8, insizea, *fp);

    

 }

  

 a->_mp_size = insizeb;

   

}





More information about the gmp-discuss mailing list