psutil - multiproceso de Python frente a subprocesos para trabajo de cpu enlazado en Windows y Linux
psutil python install windows (5)
Así que hice algo de código de prueba para ver cómo el módulo de multiprocesamiento se escalaría en el trabajo de CPU en comparación con el subprocesamiento. En Linux obtengo el aumento de rendimiento que esperaría:
linux (dual quad core xeon): serialrun took 1192.319 ms parallelrun took 346.727 ms threadedrun took 2108.172 ms
Mi dual core macbook pro muestra el mismo comportamiento:
osx (dual core macbook pro) serialrun took 2026.995 ms parallelrun took 1288.723 ms threadedrun took 5314.822 ms
Luego lo probé en una máquina con Windows y obtuve resultados muy diferentes.
windows (i7 920): serialrun took 1043.000 ms parallelrun took 3237.000 ms threadedrun took 2343.000 ms
¿Por qué, oh, por qué, el enfoque de multiprocesamiento es mucho más lento en las ventanas?
Aquí está el código de prueba:
#!/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()
Actualmente, su función counter () no está modificando mucho el estado. Intente cambiar el contador () para que modifique muchas páginas de la memoria. A continuación, ejecute un bucle enlazado de la CPU. Vea si todavía hay una gran disparidad entre Linux y Windows.
No estoy ejecutando Python 2.6 en este momento, así que no puedo probarlo yo mismo.
Apenas empezar la piscina lleva mucho tiempo. He encontrado en los programas del "mundo real" si puedo mantener un grupo abierto y reutilizarlo para muchos procesos diferentes, pasando la referencia a través de llamadas a métodos (generalmente usando map.async) y luego en Linux puedo ahorrar un poco por ciento pero en Windows A menudo puedo reducir a la mitad el tiempo empleado. Linux siempre es más rápido para mis problemas particulares, pero incluso en Windows obtengo beneficios netos del multiprocesamiento.
La documentación de Python para multiprocesamiento culpa a la falta de os.fork () por los problemas en Windows. Puede ser aplicable aquí.
Mira lo que pasa cuando importas psyco. Primero, 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
Agrega esto a la parte superior de tu script de python:
import psyco
psyco.full()
Obtengo estos resultados sin:
serialrun took 1191.000 ms
parallelrun took 3738.000 ms
threadedrun took 2728.000 ms
Obtengo estos resultados con:
serialrun took 43.000 ms
parallelrun took 3650.000 ms
threadedrun took 265.000 ms
El paralelo sigue siendo lento, pero los otros queman goma.
Edición: también, inténtalo con el grupo de multiprocesamiento. (Esta es la primera vez que intento esto y es tan rápido, me imagino que debo estar perdiendo algo).
@print_timing
def parallelpoolrun(reps):
pool = multiprocessing.Pool(processes=4)
result = pool.apply_async(counter, (reps,))
Resultados:
C:/Users/hughdbrown/Documents/python/>python 1289813.py
serialrun took 57.000 ms
parallelrun took 3716.000 ms
parallelpoolrun took 128.000 ms
threadedrun took 58.000 ms
Los procesos son mucho más ligeros bajo las variantes de UNIX. Los procesos de Windows son pesados y tardan mucho más tiempo en iniciarse. Los hilos son la forma recomendada de hacer multiprocesamiento en ventanas.
Se ha dicho que crear procesos en Windows es más caro que en Linux. Si buscas en el sitio encontrarás alguna información. Aquí hay one que encontré fácilmente.