我想用Python的任意精度計算pi使用Ramanujan的公式之一:http://en.wikipedia.org/wiki/Approximations_of_%CF%80#20th_century。它基本上需要大量的因子和高精度浮點數分割。用多線程(無加速度 - 做什麼)計算Pi
我使用多個線程劃分無限級數計算,給每個線程所有成員有一定的模數除以線程數。所以如果你有3個線程,總和應該像這樣劃分 線程1 ---> 1,4,7 ...成員 線程2 ----> 2,5,8 ... 線程3 - ---> 3,6,9 ...
這裏是我到目前爲止的代碼:
from decimal import *
from math import sqrt, ceil
from time import clock
from threading import *
import argparse
memoizedFactorials = []
memoizedFactorials.append(1)
memoizedFactorials.append(1)
class Accumulator:
def __init__(self):
self._sum = Decimal(0)
def accumulate(self, decimal):
self._sum += decimal
def sum(self):
return self._sum
def factorial(k):
if k < 2: return 1
elif len(memoizedFactorials) <= k:
product = memoizedFactorials[ - 1 ] #last element
for i in range (len(memoizedFactorials), k+1):
product *= i;
memoizedFactorials.append(product)
return memoizedFactorials[ k ]
class Worker(Thread):
def __init__(self, startIndex, step, precision, accumulator):
Thread.__init__(self, name = ("Thread - {0}".format(startIndex)))
self._startIndex = startIndex
self._step = step
self._precision = precision
self._accumulator = accumulator
def run(self):
sum = Decimal(0)
result = Decimal(1)
zero = Decimal(0)
delta = Decimal(1)/(Decimal(10)**self._precision + 1)
#print "Delta - {0}".format(delta)
i = self._startIndex
while(result - zero > delta):
numerator = Decimal(factorial(4 * i)*(1103 + 26390 * i))
denominator = Decimal((factorial(i)**4)*(396**(4*i)))
result = numerator/denominator
print "Thread - {2} --- Iteration - {0:3} --->{1:3}".format(i, result, self._startIndex)
sum += result
i += self._step
self._accumulator.accumulate(sum)
print
def main(args):
numberOfDigits = args.numberOfDigits;
getcontext().prec = numberOfDigits + 8
zero = Decimal(1)/Decimal(10**(numberOfDigits + 1))
start = clock()
accumulator = Accumulator()
threadsCount = args.numberOfThreads;
threadPool = []
for i in range(0, threadsCount):
worker = Worker(i, threadsCount, numberOfDigits, accumulator)
worker.start()
threadPool.append(worker)
for worker in threadPool:
worker.join()
sum = accumulator.sum();
rootOfTwo = Decimal(2).sqrt()
result = Decimal(9801)/(Decimal(2) * rootOfTwo * sum)
end = clock();
delta = end - start;
print result;
print ("Took it {0} second to finish".format(delta))
#testing the results
#realPiFile = open("pi.txt");
#myPi = str(result)
#realPi = realPiFile.read(len(myPi) - 1)
#if (myPi[:-1] != realPi):
# print "Answer not correct!"
# print "My pi - {0}".format(myPi)
# print "Real pi - {0}".format(realPi)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description = 'Calculate Pi at with arbitrary precision')
parser.add_argument('-p', dest = 'numberOfDigits', default=20, type = int, help ='Number of digits in pi ')
parser.add_argument('-t', '--tasks', dest = 'numberOfThreads', default=1, type = int, help ='Number of tasks(threads)')
parser.add_argument('-o', dest = 'outputFileName', type = str, help ='Connect to VCS testing servers')
parser.add_argument('-q', '--quet', dest = 'quetMode' , action='store_true', help ='Run in quet mode')
args = parser.parse_args()
print args
main(args)
a = raw_input("Press any key to continue...")
我擔心thati使用多線程時,在時間有很小或沒有加速。例如1000位圓周率: 1主題 - >0.68秒 2帖子 - >0.74秒 4帖子 - >0.75秒 10個線程 - >0.96秒
你對如何任何想法減少時間。我在任務管理器上看到,當使用四個線程時,我的兩個內核都參與100%。但時間似乎是一樣的。
PS:這是一項家庭作業,所以我不能使用另一個公式。 PSS:我使用python 2.7
謝謝:)
btw,'decimal「模塊在Python 3.3中速度快30% – jfs