Параллельный Python: 4 потока имеют одинаковую скорость с 2 потоками
Я использую Parallel Python для выполнения вычислительного кода на нескольких ядрах. У меня процессор i7-4600M, который имеет 2 ядра и 4 потока.
Интересно то, что вычисление занимает почти столько же времени, если я использую 2 или 4 тэды. Я написал небольшой пример кода, который демонстрирует это явление.
import itertools
import pp
import time
def cc(data, n):
count = 0
for A in data:
for B in itertools.product((-1,0,1), repeat=n):
inner_product = sum(a*b for a,b in zip(A,B))
if inner_product == 0:
count += 1
return count
n = 9
for thread_count in (1, 2, 3, 4):
print("Thread_count = {}".format(thread_count))
ppservers = ()
job_server = pp.Server(thread_count, ppservers=ppservers)
datas = [[] for _ in range(thread_count)]
for index, A in enumerate(itertools.product((0,1), repeat=n)):
datas[index%thread_count].append(A)
print("Data sizes: {}".format(map(len, datas)))
time_start = time.time()
jobs = [job_server.submit(cc,(data,n), (), ("itertools",)) for data in datas]
result = sum(job() for job in jobs)
time_end = time.time()
print("Time = {}".format(time_end - time_start))
print("Result = {}".format(result))
print
Вот короткое видео о запуске программы и использовании процессора: https://www.screenr.com/1ULN Когда я использую 2 потока, процессор использует 50%, если я использую 4 потока, он использует 100%. Но это только немного быстрее. Используя 2 потока, я получаю ускорение в 1,8 раза, 3 потока - в 1,9 раза, а 4 потока - в 2 раза.
Если код слишком быстрый, используйте n = 10
или же n = 11
, Но будьте осторожны, сложность 6^n
, Так n = 10
займет 6 раз столько, сколько n = 9
,
2 ответа
2 ядра и 4 потока означают, что у вас есть два гиперпотока на каждом ядре, которые не будут линейно масштабироваться, поскольку они совместно используют ресурсы и могут взаимодействовать друг с другом, в зависимости от рабочей нагрузки. Параллельный Python использует процессы и IPC за кулисами. Каждое ядро планирует два отдельных процесса, поэтому вы, вероятно, наблюдаете перегрузку кеша (кеш ядра распределяется между гиперпотоками).
Я знаю, что эта ветка немного старая, но я подумал, что некоторые дополнительные данные могут помочь. Я запустил это на виртуальной машине с 4 виртуальными процессорами (2,93 ГГц X5670 XEON) и выделенными 8 ГБ оперативной памяти. Виртуальная машина была размещена на Hyper-V и работает под управлением Python 2.7.8 на 64-битной Ubuntu 14.10, но моя версия PP - это форк PPFT.
В первом запуске число потоков было 4. Во втором я изменил цикл for, чтобы перейти к 8.
Вывод: http://pastebin.com/ByF7nbfm
Добавление еще 4 ядер и удвоение оперативной памяти, то же самое для цикла, цикл для 8:
Вывод: http://pastebin.com/irKGWMRy