Параллельный 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

Другие вопросы по тегам