Python Language
Parallell beräkning
Sök…
Anmärkningar
På grund av GIL (Global tolk-lås) körs endast en instans av python-tolk i en enda process. Så i allmänhet förbättrar användningen av flertrådar bara IO-bundna beräkningar, inte CPU-bundna. multiprocessing
rekommenderas om du vill parallellisera CPU-bundna uppgifter.
GIL gäller CPython, den mest populära implementeringen av Python, liksom PyPy. Andra implementationer som Jython och IronPython har ingen GIL .
Använda multiprocesseringsmodulen för att parallellisera uppgifter
import multiprocessing
def fib(n):
"""computing the Fibonacci in an inefficient way
was chosen to slow down the CPU."""
if n <= 2:
return 1
else:
return fib(n-1)+fib(n-2)
p = multiprocessing.Pool()
print(p.map(fib,[38,37,36,35,34,33]))
# Out: [39088169, 24157817, 14930352, 9227465, 5702887, 3524578]
Eftersom exekveringen av varje samtal till fib
sker parallellt är exekveringstiden för det fullständiga exemplet 1,8 × snabbare än om det sker på ett sekventiellt sätt på en dual processor.
Python 2.2+
Använda skript för förälder och barn för att köra kod parallellt
child.py
import time
def main():
print "starting work"
time.sleep(1)
print "work work work work work"
time.sleep(1)
print "done working"
if __name__ == '__main__':
main()
parent.py
import os
def main():
for i in range(5):
os.system("python child.py &")
if __name__ == '__main__':
main()
Detta är användbart för parallella, oberoende HTTP-förfrågnings- / svaruppgifter eller databasval / infogningar. Kommandoradsargument kan också ges till scriptet child.py . Synkronisering mellan skript kan uppnås genom att alla skript regelbundet kontrollerar en separat server (som en Redis-instans).
Använda en C-förlängning för att parallellisera uppgifter
Tanken här är att flytta de beräkningsintensiva jobb till C (med speciella makron), oberoende av Python, och låta C-koden släppa GIL medan den fungerar.
#include "Python.h"
...
PyObject *pyfunc(PyObject *self, PyObject *args) {
...
Py_BEGIN_ALLOW_THREADS
// Threaded C code
...
Py_END_ALLOW_THREADS
...
}
Använda PyPar-modulen för att parallellisera
PyPar är ett bibliotek som använder meddelandeöverföringsgränssnittet (MPI) för att tillhandahålla parallellitet i Python. Ett enkelt exempel i PyPar (se https://github.com/daleroberts/pypar) ser ut så här:
import pypar as pp
ncpus = pp.size()
rank = pp.rank()
node = pp.get_processor_name()
print 'I am rank %d of %d on node %s' % (rank, ncpus, node)
if rank == 0:
msh = 'P0'
pp.send(msg, destination=1)
msg = pp.receive(source=rank-1)
print 'Processor 0 received message "%s" from rank %d' % (msg, rank-1)
else:
source = rank-1
destination = (rank+1) % ncpus
msg = pp.receive(source)
msg = msg + 'P' + str(rank)
pypar.send(msg, destination)
pp.finalize()