многоядерная эффективность при выполнении больших вычислений?

#python #multithreading #python-2.7

#python #многопоточность #python-2.7

Вопрос:

У меня есть код для поиска больших простых чисел, поскольку он проверяет каждое нечетное число, но я хотел знать, могу ли я проверить, например, каждое другое нечетное число и проверить, чтобы числа, которые он пропускает, проверялись на другом ядре.

Комментарии:

1. Насколько мне известно, Python не выигрывает от многопоточности в плане скорости из-за GIL .

2. @rockabilly он сказал, что многоядерный. многопроцессорная обработка все еще, по крайней мере, возможна.

Ответ №1:

РЕДАКТИРОВАТЬ, добавил многопроцессорность и все еще не увидел ускорения по сравнению с unthreaded. Я не понимаю, почему многопроцессорная обработка не ускорила код, я был бы признателен за обратную связь. Возможно, я написал это неправильно. Вы можете попробовать поиграть с ним самостоятельно.

Код:

 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:]])
  

Выходной сигнал:

 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
  

..

 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
  

Комментарии:

1. Неплохо. сделайте это с несколькими процессами сейчас