<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:p="urn:schemas-microsoft-com:office:powerpoint" xmlns:a="urn:schemas-microsoft-com:office:access" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema" xmlns:b="urn:schemas-microsoft-com:office:publisher" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:c="urn:schemas-microsoft-com:office:component:spreadsheet" xmlns:odc="urn:schemas-microsoft-com:office:odc" xmlns:oa="urn:schemas-microsoft-com:office:activation" xmlns:html="http://www.w3.org/TR/REC-html40" xmlns:q="http://schemas.xmlsoap.org/soap/envelope/" xmlns:D="DAV:" xmlns:x2="http://schemas.microsoft.com/office/excel/2003/xml" xmlns:ois="http://schemas.microsoft.com/sharepoint/soap/ois/" xmlns:dir="http://schemas.microsoft.com/sharepoint/soap/directory/" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:dsp="http://schemas.microsoft.com/sharepoint/dsp" xmlns:udc="http://schemas.microsoft.com/data/udc" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sub="http://schemas.microsoft.com/sharepoint/soap/2002/1/alerts/" xmlns:ec="http://www.w3.org/2001/04/xmlenc#" xmlns:sp="http://schemas.microsoft.com/sharepoint/" xmlns:sps="http://schemas.microsoft.com/sharepoint/soap/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:udcxf="http://schemas.microsoft.com/data/udc/xmlfile" xmlns:wf="http://schemas.microsoft.com/sharepoint/soap/workflow/" xmlns:mver="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns:mrels="http://schemas.openxmlformats.org/package/2006/relationships" xmlns:ex12t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:ex12m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:Z="urn:schemas-microsoft-com:" xmlns:st="&#1;" xmlns="http://www.w3.org/TR/REC-html40">

<head>
<meta http-equiv=Content-Type content="text/html; charset=us-ascii">
<meta name=Generator content="Microsoft Word 12 (filtered medium)">
<style>
<!--
 /* Font Definitions */
 @font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
 /* Style Definitions */
 p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri","sans-serif";}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
pre
        {mso-style-priority:99;
        mso-style-link:"HTML Preformatted Char";
        margin:0in;
        margin-bottom:.0001pt;
        font-size:10.0pt;
        font-family:"Courier New";}
span.EmailStyle17
        {mso-style-type:personal-compose;
        font-family:"Calibri","sans-serif";
        color:windowtext;}
span.HTMLPreformattedChar
        {mso-style-name:"HTML Preformatted Char";
        mso-style-priority:99;
        mso-style-link:"HTML Preformatted";
        font-family:"Courier New";}
.MsoChpDefault
        {mso-style-type:export-only;}
@page Section1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.Section1
        {page:Section1;}
-->
</style>
<!--[if gte mso 9]><xml>
 <o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
 <o:shapelayout v:ext="edit">
  <o:idmap v:ext="edit" data="1" />
 </o:shapelayout></xml><![endif]-->
</head>

<body lang=EN-US link=blue vlink=purple>

<div class=Section1>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>Hi!<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>Since
GNU GCC 4.3 now supports OpenMP and most new AMD and Intel processors have more
than one core, I thought a parallel version of the gmp-chudnovsky program would
be an interesting exercise.&nbsp; This simple parallel version of
gmp-chudnovsky has the factorization performance enhancement removed, so
running with one core will not be as fast as the original version.&nbsp; I hope
to post a parallel version with the factorization performance enhancement in
the near future.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>Later,<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>David
Carver<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;<o:p></o:p></span></p>

<pre>/* Pi computation using Chudnovsky's algortithm.<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre> * Copyright 2002, 2005 Hanhong Xue (macroxue at yahoo dot com)<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre> * Slightly modified 2005 by Torbjorn Granlund (tege at swox dot com) to allow<o:p></o:p></pre><pre>&nbsp;&nbsp; more than 2G digits to be computed.<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre> * Modifed 2008 by David Carver (dcarver at tacc dot utexas dot edu) to enable<o:p></o:p></pre><pre>&nbsp;&nbsp; multi-threading using the algorithm from &quot;Computation of High-Precision <o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;Mathematical Constants in a Combined Cluster and Grid Environment&quot; by <o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;Daisuke Takahashi, Mitsuhisa Sato, and Taisuke Boku.&nbsp; <o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp;&nbsp; For GNU gcc 4.3<o:p></o:p></pre><pre>&nbsp;&nbsp; gcc -fopenmp -Wall -O2 -o pgmp-chudnovsky pchudnovsky.c -lgmp -lm<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp;&nbsp; For Intel 10.1 compiler<o:p></o:p></pre><pre>&nbsp;&nbsp; icc -openmp -O2 -o pgmp-chudnovsky pgmp-chudnovsky.c -lgmp -lm<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp;&nbsp; For AIX xlc<o:p></o:p></pre><pre>&nbsp;&nbsp; xlc_r -qsmp=omp -O2 -o pgmp-chudnovsky pchudnovsky.c&nbsp; -lgmp -lm<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre> * Redistribution and use in source and binary forms, with or without<o:p></o:p></pre><pre> * modification, are permitted provided that the following conditions are met:<o:p></o:p></pre><pre> * 1. Redistributions of source code must retain the above copyright notice,<o:p></o:p></pre><pre> * this list of conditions and the following disclaimer.<o:p></o:p></pre><pre> * 2. Redistributions in binary form must reproduce the above copyright notice,<o:p></o:p></pre><pre> * this list of conditions and the following disclaimer in the documentation<o:p></o:p></pre><pre> * and/or other materials provided with the distribution.<o:p></o:p></pre><pre> *<o:p></o:p></pre><pre> * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR<o:p></o:p></pre><pre> * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF<o:p></o:p></pre><pre> * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.&nbsp; IN NO<o:p></o:p></pre><pre> * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,<o:p></o:p></pre><pre> * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,<o:p></o:p></pre><pre> * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;<o:p></o:p></pre><pre> * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,<o:p></o:p></pre><pre> * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR<o:p></o:p></pre><pre> * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF<o:p></o:p></pre><pre> * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.<o:p></o:p></pre><pre> */<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>#include &lt;assert.h&gt;<o:p></o:p></pre><pre>#include &lt;math.h&gt;<o:p></o:p></pre><pre>#include &lt;stdio.h&gt;<o:p></o:p></pre><pre>#include &lt;stdlib.h&gt;<o:p></o:p></pre><pre>#include &lt;string.h&gt;<o:p></o:p></pre><pre>#include &lt;time.h&gt;<o:p></o:p></pre><pre>#include &quot;gmp.h&quot;<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>#define A &nbsp;&nbsp;13591409<o:p></o:p></pre><pre>#define B&nbsp;&nbsp; 545140134<o:p></o:p></pre><pre>#define C&nbsp;&nbsp; 640320<o:p></o:p></pre><pre>#define D&nbsp;&nbsp; 12<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>#define BITS_PER_DIGIT&nbsp;&nbsp; 3.32192809488736234787<o:p></o:p></pre><pre>#define DIGITS_PER_ITER&nbsp; 14.1816474627254776555<o:p></o:p></pre><pre>#define DOUBLE_PREC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 53<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>char *prog_name;<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>#if CHECK_MEMUSAGE<o:p></o:p></pre><pre>#undef CHECK_MEMUSAGE<o:p></o:p></pre><pre>#define CHECK_MEMUSAGE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \<o:p></o:p></pre><pre>&nbsp; do {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; char buf[100];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; snprintf (buf, 100,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;ps aguxw | grep '[%c]%s'&quot;, prog_name[0], prog_name+1);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; system (buf);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \<o:p></o:p></pre><pre>&nbsp; } while (0)<o:p></o:p></pre><pre>#else<o:p></o:p></pre><pre>#undef CHECK_MEMUSAGE<o:p></o:p></pre><pre>#define CHECK_MEMUSAGE<o:p></o:p></pre><pre>#endif<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>////////////////////////////////////////////////////////////////////////////<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>mpf_t t1, t2;<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>// r = sqrt(x)<o:p></o:p></pre><pre>void<o:p></o:p></pre><pre>my_sqrt_ui(mpf_t r, unsigned long x)<o:p></o:p></pre><pre>{<o:p></o:p></pre><pre>&nbsp; unsigned long prec, bits, prec0;<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; prec0 = mpf_get_prec(r);<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; if (prec0&lt;=DOUBLE_PREC) {<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; mpf_set_d(r, sqrt(x));<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; return;<o:p></o:p></pre><pre>&nbsp; }<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; bits = 0;<o:p></o:p></pre><pre>&nbsp; for (prec=prec0; prec&gt;DOUBLE_PREC;) {<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; int bit = prec&amp;1;<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; prec = (prec+bit)/2;<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; bits = bits*2+bit;<o:p></o:p></pre><pre>&nbsp; }<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; mpf_set_prec_raw(t1, DOUBLE_PREC);<o:p></o:p></pre><pre>&nbsp; mpf_set_d(t1, 1/sqrt(x));<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; while (prec&lt;prec0) {<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; prec *=2;<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; if (prec&lt;prec0) {<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* t1 = t1+t1*(1-x*t1*t1)/2; */<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mpf_set_prec_raw(t2, prec);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mpf_mul(t2, t1, t1);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // half x half -&gt; full<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mpf_mul_ui(t2, t2, x);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mpf_ui_sub(t2, 1, t2);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mpf_set_prec_raw(t2, prec/2);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mpf_div_2exp(t2, t2, 1);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mpf_mul(t2, t2, t1);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // half x half -&gt; half<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mpf_set_prec_raw(t1, prec);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mpf_add(t1, t1, t2);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; } else {<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; prec = prec0;<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* t2=x*t1, t1 = t2+t1*(x-t2*t2)/2; */<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mpf_set_prec_raw(t2, prec/2);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mpf_mul_ui(t2, t1, x);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mpf_mul(r, t2, t2);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // half x half -&gt; full<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mpf_ui_sub(r, x, r);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mpf_mul(t1, t1, r);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // half x half -&gt; half<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mpf_div_2exp(t1, t1, 1);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mpf_add(r, t1, t2);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; }<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; prec -= (bits&amp;1);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; bits /=2;<o:p></o:p></pre><pre>&nbsp; }<o:p></o:p></pre><pre>}<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>// r = y/x&nbsp;&nbsp; WARNING: r cannot be the same as y.<o:p></o:p></pre><pre>void<o:p></o:p></pre><pre>my_div(mpf_t r, mpf_t y, mpf_t x)<o:p></o:p></pre><pre>{<o:p></o:p></pre><pre>&nbsp; unsigned long prec, bits, prec0;<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; prec0 = mpf_get_prec(r);<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; if (prec0&lt;=DOUBLE_PREC) {<o:p></o:p></pre><pre>&nbsp;&nbsp; &nbsp;mpf_set_d(r, mpf_get_d(y)/mpf_get_d(x));<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; return;<o:p></o:p></pre><pre>&nbsp; }<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; bits = 0;<o:p></o:p></pre><pre>&nbsp; for (prec=prec0; prec&gt;DOUBLE_PREC;) {<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; int bit = prec&amp;1;<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; prec = (prec+bit)/2;<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; bits = bits*2+bit;<o:p></o:p></pre><pre>&nbsp; }<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; mpf_set_prec_raw(t1, DOUBLE_PREC);<o:p></o:p></pre><pre>&nbsp; mpf_ui_div(t1, 1, x);<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; while (prec&lt;prec0) {<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; prec *=2;<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; if (prec&lt;prec0) {<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* t1 = t1+t1*(1-x*t1); */<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mpf_set_prec_raw(t2, prec);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mpf_mul(t2, x, t1);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // full x half -&gt; full<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mpf_ui_sub(t2, 1, t2);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mpf_set_prec_raw(t2, prec/2);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mpf_mul(t2, t2, t1);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // half x half -&gt; half<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mpf_set_prec_raw(t1, prec);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mpf_add(t1, t1, t2);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; } else {<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; prec = prec0;<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* t2=y*t1, t1 = t2+t1*(y-x*t2); */<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mpf_set_prec_raw(t2, prec/2);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mpf_mul(t2, t1, y);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;// half x half -&gt; half<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mpf_mul(r, x, t2);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // full x half -&gt; full<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mpf_sub(r, y, r);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mpf_mul(t1, t1, r);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // half x half -&gt; half<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mpf_add(r, t1, t2);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; }<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; prec -= (bits&amp;1);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; bits /=2;<o:p></o:p></pre><pre>&nbsp; }<o:p></o:p></pre><pre>}<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>////////////////////////////////////////////////////////////////////////////<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out=0;<o:p></o:p></pre><pre>mpz_t&nbsp;&nbsp; **pstack, **qstack, **gstack;<o:p></o:p></pre><pre>long int cores=1, depth, cores_depth;<o:p></o:p></pre><pre>double&nbsp;&nbsp; progress=0, percent;<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>// binary splitting<o:p></o:p></pre><pre>void<o:p></o:p></pre><pre>sum(unsigned long i, unsigned long j, unsigned long gflag)<o:p></o:p></pre><pre>{<o:p></o:p></pre><pre>&nbsp; mpz_mul(pstack[i][0], pstack[i][0], pstack[j][0]);<o:p></o:p></pre><pre>&nbsp; mpz_mul(qstack[i][0], qstack[i][0], pstack[j][0]);<o:p></o:p></pre><pre>&nbsp; mpz_mul(qstack[j][0], qstack[j][0], gstack[i][0]);<o:p></o:p></pre><pre>&nbsp; mpz_add(qstack[i][0], qstack[i][0], qstack[j][0]);<o:p></o:p></pre><pre>&nbsp; if (gflag) {<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp; mpz_mul(gstack[i][0], gstack[i][0], gstack[j][0]);<o:p></o:p></pre><pre>&nbsp; }<o:p></o:p></pre><pre>}<o:p></o:p></pre><pre>void<o:p></o:p></pre><pre>bs(unsigned long a, unsigned long b, unsigned long gflag, unsigned long level, unsigned long index, unsigned long top)<o:p></o:p></pre><pre>{<o:p></o:p></pre><pre>&nbsp; unsigned long mid;<o:p></o:p></pre><pre>&nbsp; int ccc;<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; if (out&amp;2) {<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; fprintf(stderr,&quot;bs: a = %ld b = %ld gflag = %ld index = %ld level = %ld top = %ld \n&quot;, a,b,gflag,index,level,top);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; fflush(stderr);<o:p></o:p></pre><pre>&nbsp; }<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; if ((b &gt; a) &amp;&amp; (b-a==1)) {<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; /*<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; g(b-1,b) = (6b-5)(2b-1)(6b-1)<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p(b-1,b) = b^3 * C^3 / 24<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; q(b-1,b) = (-1)^b*g(b-1,b)*(A+Bb).<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; */<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; mpz_set_ui(pstack[index][top], b);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; mpz_mul_ui(pstack[index][top], pstack[index][top], b);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; mpz_mul_ui(pstack[index][top], pstack[index][top], b);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; mpz_mul_ui(pstack[index][top], pstack[index][top], (C/24)*(C/24));<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; mpz_mul_ui(pstack[index][top], pstack[index][top], C*24);<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp;&nbsp;&nbsp; mpz_set_ui(gstack[index][top], 2*b-1);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; mpz_mul_ui(gstack[index][top], gstack[index][top], 6*b-1);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; mpz_mul_ui(gstack[index][top], gstack[index][top], 6*b-5);<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp;&nbsp;&nbsp; mpz_set_ui(qstack[index][top], b);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; mpz_mul_ui(qstack[index][top], qstack[index][top], B);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; mpz_add_ui(qstack[index][top], qstack[index][top], A);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; mpz_mul&nbsp;&nbsp; (qstack[index][top], qstack[index][top], gstack[index][top]);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; if (b%2)<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mpz_neg(qstack[index][top], qstack[index][top]);<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp;&nbsp;&nbsp; if (b&gt;(int)(progress)) {<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fprintf(stderr,&quot;.&quot;); fflush(stderr);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; progress += percent*2;<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; }<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; } else {<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; /*<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p(a,b) = p(a,m) * p(m,b)<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; g(a,b) = g(a,m) * g(m,b)<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; q(a,b) = q(a,m) * p(m,b) + q(m,b) * g(a,m)<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; */<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; mid = a+(b-a)*0.5224;&nbsp;&nbsp;&nbsp;&nbsp; // tuning parameter<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; bs(a, mid, 1, level+1, index, top);<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp;&nbsp;&nbsp; bs(mid, b, gflag, level+1, index, top+1);<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp;&nbsp;&nbsp; ccc = level == 0;<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp;&nbsp;&nbsp; if (ccc) CHECK_MEMUSAGE;<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; mpz_mul(pstack[index][top], pstack[index][top], pstack[index][top+1]);<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp;&nbsp;&nbsp; if (ccc) CHECK_MEMUSAGE;<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; mpz_mul(qstack[index][top], qstack[index][top], pstack[index][top+1]);<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp;&nbsp;&nbsp; if (ccc) CHECK_MEMUSAGE;<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; mpz_mul(qstack[index][top+1], qstack[index][top+1], gstack[index][top]);<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp;&nbsp;&nbsp; if (ccc) CHECK_MEMUSAGE;<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; mpz_add(qstack[index][top], qstack[index][top], qstack[index][top+1]);<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp;&nbsp;&nbsp; if (gflag) {<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mpz_mul(gstack[index][top], gstack[index][top], gstack[index][top+1]);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; }<o:p></o:p></pre><pre>&nbsp; }<o:p></o:p></pre><pre>}<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>int<o:p></o:p></pre><pre>main(int argc, char *argv[])<o:p></o:p></pre><pre>{<o:p></o:p></pre><pre>&nbsp; mpf_t&nbsp; pi, qi;<o:p></o:p></pre><pre>&nbsp; long int d=100, terms, i, j, k, cores_size;<o:p></o:p></pre><pre>&nbsp; unsigned long psize, qsize, mid;<o:p></o:p></pre><pre>&nbsp; clock_t begin, mid0, mid1, mid2, mid3, mid4, end;<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; prog_name = argv[0];<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; if (argc==1) {<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; fprintf(stderr,&quot;\nSyntax: %s &lt;digits&gt; &lt;option&gt; &lt;cores&gt;\n&quot;,prog_name);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; fprintf(stderr,&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;digits&gt; digits of pi to output\n&quot;);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; fprintf(stderr,&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;option&gt; 0 - just run (default)\n&quot;);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; fprintf(stderr,&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 - output digits\n&quot;);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; fprintf(stderr,&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2 - debug\n&quot;);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; fprintf(stderr,&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;cores&gt; number of cores (default 1)\n&quot;);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; exit(1);<o:p></o:p></pre><pre>&nbsp; }<o:p></o:p></pre><pre>&nbsp; if (argc&gt;1)<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; d = strtoul(argv[1], 0, 0);<o:p></o:p></pre><pre>&nbsp; if (argc&gt;2)<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; out = atoi(argv[2]);<o:p></o:p></pre><pre>&nbsp; if (argc&gt;3)<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; cores = atoi(argv[3]);<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; terms = d/DIGITS_PER_ITER;<o:p></o:p></pre><pre>&nbsp; depth = 0;<o:p></o:p></pre><pre>&nbsp; while ((1L&lt;&lt;depth)&lt;terms)<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; depth++;<o:p></o:p></pre><pre>&nbsp; depth++;<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; if (cores &lt; 1) {<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fprintf(stderr,&quot;Number of cores reset from %ld to 1\n&quot;,cores); <o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fflush(stderr);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cores = 1;<o:p></o:p></pre><pre>&nbsp; }<o:p></o:p></pre><pre>&nbsp; if ((terms &gt; 0) &amp;&amp; (terms &lt; cores)) {<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fprintf(stderr,&quot;Number of cores reset from %ld to %ld\n&quot;,cores,terms); <o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fflush(stderr);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cores = terms;<o:p></o:p></pre><pre>&nbsp; }<o:p></o:p></pre><pre>&nbsp; cores_depth = 0;<o:p></o:p></pre><pre>&nbsp; while ((1L&lt;&lt;cores_depth)&lt;cores)<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; cores_depth++;<o:p></o:p></pre><pre>&nbsp; cores_size=pow(2,cores_depth);<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; percent = terms/100.0;<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; fprintf(stderr,&quot;#terms=%ld, depth=%ld, cores=%ld\n&quot;, terms, depth, cores);<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; begin = mid0 = clock();<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; pstack = malloc(sizeof(mpz_t)*cores);<o:p></o:p></pre><pre>&nbsp; qstack = malloc(sizeof(mpz_t)*cores);<o:p></o:p></pre><pre>&nbsp; gstack = malloc(sizeof(mpz_t)*cores);<o:p></o:p></pre><pre>&nbsp; /* allocate stacks */<o:p></o:p></pre><pre>&nbsp; for (j = 0; j &lt; cores_size; j++) {<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; pstack[j] = malloc(sizeof(mpz_t)*depth);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; qstack[j] = malloc(sizeof(mpz_t)*depth);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; gstack[j] = malloc(sizeof(mpz_t)*depth);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; depth; i++) {<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mpz_init(pstack[j][i]);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mpz_init(qstack[j][i]);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;mpz_init(gstack[j][i]);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; }<o:p></o:p></pre><pre>&nbsp; }<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre> <o:p></o:p></pre><pre>&nbsp;&nbsp;/* begin binary splitting process */<o:p></o:p></pre><pre>&nbsp; if (terms&lt;=0) {<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; mpz_set_ui(pstack[0][0],1);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; mpz_set_ui(qstack[0][0],0);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; mpz_set_ui(gstack[0][0],1);<o:p></o:p></pre><pre>&nbsp; } else {<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp;&nbsp;&nbsp; mid0 = clock();<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp;&nbsp;&nbsp; mid = terms / cores; <o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>#ifdef _OPENMP<o:p></o:p></pre><pre>#pragma omp parallel for<o:p></o:p></pre><pre>#endif<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; cores; i++) {<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (i &lt; (cores-1))<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bs(i*mid, (i+1)*mid, 1, 0, i, 0);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bs(i*mid, terms, 1, 0, i, 0);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; }<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp;&nbsp;&nbsp; for (k = 1; k &lt; cores_size; k*=2) {<o:p></o:p></pre><pre>#ifdef _OPENMP<o:p></o:p></pre><pre>#pragma omp parallel for<o:p></o:p></pre><pre>#endif<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; cores; i=i+2*k) {<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (i+k &lt; cores) {<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sum( i, i+k, 1);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; }<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp;&nbsp;&nbsp; for (j=0; j&lt;cores_size; j++) {<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; free(gstack[j]);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; }<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; free(gstack);<o:p></o:p></pre><pre>&nbsp; }<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; mid1 = clock();<o:p></o:p></pre><pre>&nbsp; fprintf(stderr,&quot;\nbs&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; time = %6.3f\n&quot;, (double)(mid1-mid0)/CLOCKS_PER_SEC);<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; /* prepare to convert integers to floats */<o:p></o:p></pre><pre>&nbsp; mpf_set_default_prec((long int)(d*BITS_PER_DIGIT+16));<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; /*<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; p*(C/D)*sqrt(C)<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; pi = -----------------<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; (q+A*p)<o:p></o:p></pre><pre>&nbsp; */<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; psize = mpz_sizeinbase(pstack[0][0],10);<o:p></o:p></pre><pre>&nbsp; qsize = mpz_sizeinbase(qstack[0][0],10);<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; mpz_addmul_ui(qstack[0][0], pstack[0][0], A);<o:p></o:p></pre><pre>&nbsp; mpz_mul_ui(pstack[0][0], pstack[0][0], C/D);<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; mpf_init(pi);<o:p></o:p></pre><pre>&nbsp; mpf_set_z(pi, pstack[0][0]);<o:p></o:p></pre><pre>&nbsp; mpz_clear(pstack[0][0]);<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; mpf_init(qi);<o:p></o:p></pre><pre>&nbsp; mpf_set_z(qi, qstack[0][0]);<o:p></o:p></pre><pre>&nbsp; mpz_clear(qstack[0][0]);<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; free(pstack[0]);<o:p></o:p></pre><pre>&nbsp; free(qstack[0]);<o:p></o:p></pre><pre>&nbsp; free(pstack);<o:p></o:p></pre><pre>&nbsp; free(qstack);<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; mid2 = clock();<o:p></o:p></pre><pre>&nbsp; //fprintf(stderr,&quot;time = %6.3f\n&quot;, (double)(mid2-mid1)/CLOCKS_PER_SEC);<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; /* initialize temp float variables for sqrt &amp; div */<o:p></o:p></pre><pre>&nbsp; mpf_init(t1);<o:p></o:p></pre><pre>&nbsp; mpf_init(t2);<o:p></o:p></pre><pre>&nbsp; //mpf_set_prec_raw(t1, mpf_get_prec(pi));<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; /* final step */<o:p></o:p></pre><pre>&nbsp; fprintf(stderr,&quot;div&nbsp;&nbsp;&nbsp;&nbsp; &quot;);&nbsp; fflush(stderr);<o:p></o:p></pre><pre>&nbsp; my_div(qi, pi, qi);<o:p></o:p></pre><pre>&nbsp; mid3 = clock();<o:p></o:p></pre><pre>&nbsp; fprintf(stderr,&quot;time = %6.3f\n&quot;, (double)(mid3-mid2)/CLOCKS_PER_SEC);<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; fprintf(stderr,&quot;sqrt&nbsp;&nbsp;&nbsp; &quot;);&nbsp; fflush(stderr);<o:p></o:p></pre><pre>&nbsp; my_sqrt_ui(pi, C);<o:p></o:p></pre><pre>&nbsp; mid4 = clock();<o:p></o:p></pre><pre>&nbsp; fprintf(stderr,&quot;time = %6.3f\n&quot;, (double)(mid4-mid3)/CLOCKS_PER_SEC);<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; fprintf(stderr,&quot;mul&nbsp;&nbsp;&nbsp;&nbsp; &quot;);&nbsp; fflush(stderr);<o:p></o:p></pre><pre>&nbsp; mpf_mul(qi, qi, pi);<o:p></o:p></pre><pre>&nbsp; end = clock();<o:p></o:p></pre><pre>&nbsp; fprintf(stderr,&quot;time = %6.3f\n&quot;, (double)(end-mid4)/CLOCKS_PER_SEC);<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; fprintf(stderr,&quot;total&nbsp;&nbsp; time = %6.3f\n&quot;, (double)(end-begin)/CLOCKS_PER_SEC);<o:p></o:p></pre><pre>&nbsp; fflush(stderr);<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; fprintf(stderr,&quot;&nbsp;&nbsp; P size=%ld digits (%f)\n&quot;<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  &quot;&nbsp;&nbsp; Q size=%ld digits (%f)\n&quot;,<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  psize, (double)psize/d, qsize, (double)qsize/d);<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; /* output Pi and timing statistics */<o:p></o:p></pre><pre>&nbsp; if (out&amp;1)&nbsp; {<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; fprintf(stdout,&quot;pi(0,%ld)=\n&quot;, terms);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; mpf_out_str(stdout, 10, d+2, qi);<o:p></o:p></pre><pre>&nbsp;&nbsp;&nbsp; fprintf(stdout,&quot;\n&quot;);<o:p></o:p></pre><pre>&nbsp; }<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; /* free float resources */<o:p></o:p></pre><pre>&nbsp; mpf_clear(pi);<o:p></o:p></pre><pre>&nbsp; mpf_clear(qi);<o:p></o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>&nbsp; mpf_clear(t1);<o:p></o:p></pre><pre>&nbsp; mpf_clear(t2);<o:p></o:p></pre><pre>&nbsp; exit (0);<o:p></o:p></pre><pre>}<o:p></o:p></pre>

<p class=MsoNormal><o:p>&nbsp;</o:p></p>

</div>

</body>

</html>