# PrimeCounter.py # Python has multi-threading, but that doesn't take advantage of multiple cores because # of an underlying global interpreter lock (GIL) # the code below generates the correct answer for the threaded code, but only one processor is used from threading import Thread as Worker import time class PrimeCounter(Worker): # typedef struct { # int id; # int N; # int chunk_size; # int num_threads; # int count; # } ThreadInfo; def __init__ (self, id, N, chunk_size, num_threads ): super().__init__() self.id = id self.N = N self.chunk_size = chunk_size self.num_threads = num_threads self.count = 0 def is_prime (self, n): if (n < 2): return False if (n == 2): return True if (n % 2 == 0): return False for i in range (3, n, 2): if (n % i == 0): return False; return True def run (self): print( "running with id", self.id ) # int start = ti->chunk_size * ti->id; # for (int i = start; i < ti->N; i = i + ti->chunk_size*ti->num_threads ) { # for (int j = 0; j < ti->chunk_size; j++) { start = self.chunk_size*self.id for i in range( start, self.N, self.chunk_size*self.num_threads): for j in range(0, self.chunk_size ): if self.is_prime(i+j): self.count += 1 return 0 def getCount (self): return self.count def main (): N = 100000 NUM_THREADS = 8 pc = [] for i in range(NUM_THREADS): pc.append( PrimeCounter( id=i, N=N, chunk_size=100, num_threads=NUM_THREADS) ) pc0 = PrimeCounter( id=0, N=N, chunk_size=N, num_threads=1) t1 = time.time() for i in range(NUM_THREADS): pc[i].start() for i in range(NUM_THREADS): pc[i].join() count = 0 for i in range(NUM_THREADS): count += pc[i].getCount() t2 = time.time() print("multi-thread count ", count, " primes") print("time is ", t2 - t1) t1 = time.time() pc0.start() pc0.join() t2 = time.time() print("1 thread count ", pc0.getCount(), " primes") print("time is ", t2 - t1) if __name__ == "__main__": main()