multi-core efficiency when doing big computations?
<p>I have a code to find big primes, as it is it checks every odd number, but I wanted to know if I could have it check, for example, every other odd number and have the numbers it skips be checked on a different core.</p>

<p>EDIT, added multiprocess and still didn't see a speedup over unthreaded. I don't understand why multiprocessing didn't speed up the code, I'd appreciate feedback. Maybe I didn't write it correctly. You can try playing with it yourself.</p>

<p>Code:</p>

<pre><code>from multiprocessing import Process, Queue
from threading import Thread
import time

#Function to determine if 'a' is prime, used by all methods
def is_prime(a):
    return all(a % i for i in xrange(2, a))

#Look for primes between 'min_prime' and 'max_prime'
min_prime = 3 #must start on odd number!
max_prime = 200000
num_threads = 8
times = {}
primes = {}

#######################
#Multiprocess approach#
#######################
def get_primes(q,start_val,num_threads,max_prime):
    vals = range(start_val,max_prime,num_threads*2)
    q.put([val for val in vals if is_prime(val)])

start_processes_time = time.time()
q = Queue()
processes = []
for i in range(num_threads):
    start = i*2+min_prime
    p = Process(target=get_primes,args=(q,start,num_threads,max_prime+1,))
    processes.append(p)
    p.start()

#Wait for all of them to stop
process_primes = set()
for p in processes:
    p.join()
    process_primes.update(q.get())

times["Processes"] = time.time()-start_processes_time
primes["Processes"] = process_primes

####################
#Threading approach#
####################
class PrimeThread(Thread):
    __slots__ = ["start_val","num_threads","max_prime","vals","primes"]
    def __init__(self,start_val,num_threads,max_prime):
        self.start_val = start_val
        self.num_threads = num_threads
        self.stop = max_prime
        super(PrimeThread, self).__init__()

    def run(self):
        self.vals = range(self.start_val,self.stop,self.num_threads*2)
        self.primes = {val for val in self.vals if is_prime(val)}

threads = []

start_thread_time = time.time()
for i in range(num_threads):
    start = i*2+min_prime
    t = PrimeThread(start,num_threads,max_prime+1)
    threads.append(t)
    t.start()

thread_primes = set()
for t in threads:
    t.join()
    thread_primes.update(t.primes)

times["Threading"] = time.time()-start_thread_time
primes["Threading"] = thread_primes

#######################
#Non-threaded approach#
#######################
start_no_thread_time = time.time()
no_thread_primes = {val for val in range(min_prime,max_prime+1,2) if is_prime(val)}
times["Threadless"] = time.time()-start_no_thread_time
primes["Threadless"] = no_thread_primes

###############
#Compare times#
###############
all_found_same_primes = all([p1 == p2 for p1 in primes.values() for p2 in primes.values()])
print "For min_prime=",min_prime,"max_prime=",max_prime,"and",num_threads,"threads:"
print "All methods found same primes:",all_found_same_primes,"\n"

times = sorted(times.items(), key=lambda x: x[1])
print "\n".join([l+" time: "+str(t) for l,t in times]),"\n"

f_m,f_t = times[0] #get fastest method (f_m) and fastest time (f_t)
print f_m,"was"," and ".join([str(t/f_t)+" times faster than "+l for l,t in times[1:]])
</code></pre>

<p>Output:</p>

<pre><code>For min_prime = 3 max_prime = 23 and 8 threads:
All methods found same primes: True

Threadless time: 2.50339508057e-05
Threading time: 0.00144100189209
Processes time: 0.0272209644318

Threadless was 57.5619047619 times faster than Threading and 1087.36190476 times faster than Processes
</code></pre>

<p>..</p>

<pre><code>For min_prime = 3 max_prime = 200000 and 8 threads:
All methods found same primes: True

Threadless time: 149.900467873
Processes time: 166.985640049
Threading time: 668.010253906

Threadless was 1.11397677685 times faster than Processes and 4.45635869845 times faster than Threading
</code></pre>

python multithreading python-2.7