Ответ 1
Процессы намного более легкие в вариантах UNIX. Процессы Windows тяжелы и требуют гораздо больше времени для запуска. Темы - рекомендуемый способ многопроцессорности в Windows.
Итак, я выбил несколько тестовых кодов, чтобы увидеть, как модуль многопроцессорности будет масштабироваться на связанной с процессором работе по сравнению с потоковой обработкой. В linux я получаю увеличение производительности, которое я ожидаю:
linux (dual quad core xeon): serialrun took 1192.319 ms parallelrun took 346.727 ms threadedrun took 2108.172 ms
Мой двухъядерный macbook pro показывает такое же поведение:
osx (dual core macbook pro) serialrun took 2026.995 ms parallelrun took 1288.723 ms threadedrun took 5314.822 ms
Затем я пошел и попробовал его на машине с Windows и получил очень разные результаты.
windows (i7 920): serialrun took 1043.000 ms parallelrun took 3237.000 ms threadedrun took 2343.000 ms
Почему, почему, многопроцессорный подход намного медленнее на окнах?
Здесь тестовый код:
#!/usr/bin/env python import multiprocessing import threading import time def print_timing(func): def wrapper(*arg): t1 = time.time() res = func(*arg) t2 = time.time() print '%s took %0.3f ms' % (func.func_name, (t2-t1)*1000.0) return res return wrapper def counter(): for i in xrange(1000000): pass @print_timing def serialrun(x): for i in xrange(x): counter() @print_timing def parallelrun(x): proclist = [] for i in xrange(x): p = multiprocessing.Process(target=counter) proclist.append(p) p.start() for i in proclist: i.join() @print_timing def threadedrun(x): threadlist = [] for i in xrange(x): t = threading.Thread(target=counter) threadlist.append(t) t.start() for i in threadlist: i.join() def main(): serialrun(50) parallelrun(50) threadedrun(50) if __name__ == '__main__': main()
Процессы намного более легкие в вариантах UNIX. Процессы Windows тяжелы и требуют гораздо больше времени для запуска. Темы - рекомендуемый способ многопроцессорности в Windows.
Документация python для многопроцессорности винит в отсутствии os.fork() проблемы в Windows. Он может быть применим здесь.
Посмотрите, что произойдет, когда вы импортируете psyco. Во-первых, easy_install it:
C:\Users\hughdbrown>\Python26\scripts\easy_install.exe psyco
Searching for psyco
Best match: psyco 1.6
Adding psyco 1.6 to easy-install.pth file
Using c:\python26\lib\site-packages
Processing dependencies for psyco
Finished processing dependencies for psyco
Добавьте это в начало вашего python script:
import psyco
psyco.full()
Я получаю эти результаты без:
serialrun took 1191.000 ms
parallelrun took 3738.000 ms
threadedrun took 2728.000 ms
Я получаю следующие результаты:
serialrun took 43.000 ms
parallelrun took 3650.000 ms
threadedrun took 265.000 ms
Параллельно все еще медленно, но остальные сжигают резину.
Изменить: также попробуйте его с многопроцессорным пулом. (Это мой первый раз, когда я пытаюсь это сделать, и это так быстро, я полагаю, что мне что-то не хватает.)
@print_timing
def parallelpoolrun(reps):
pool = multiprocessing.Pool(processes=4)
result = pool.apply_async(counter, (reps,))
Результаты:
C:\Users\hughdbrown\Documents\python\StackOverflow>python 1289813.py
serialrun took 57.000 ms
parallelrun took 3716.000 ms
parallelpoolrun took 128.000 ms
threadedrun took 58.000 ms
Было сказано, что создание процессов в Windows дороже, чем на Linux. Если вы ищете по сайту, вы найдете некоторую информацию. Здесь один я нашел легко.
В настоящее время ваша функция counter() не модифицирует много состояний. Попробуйте изменить счетчик(), чтобы он изменял многие страницы памяти. Затем запустите cpu bound loop. Посмотрите, есть ли еще большое несоответствие между linux и окнами.
Я не запускаю python 2.6 прямо сейчас, поэтому сам не могу попробовать.
Простое начало пула занимает много времени. Я нашел в программах "реального мира", если я могу оставить пул открытым и повторно использовать его для многих разных процессов, передав ссылку через вызовы методов (обычно используя map.async), а затем в Linux я могу сэкономить несколько процентов, но в Windows Я часто могу сократить вдвое время. Linux всегда быстрее для моих конкретных проблем, но даже в Windows я получаю чистые преимущества от многопроцессорности.