python multi-threading plus lent que la série?
Je suis à essayer de comprendre le multi-threading de la programmation en python. Voici la simple tâche avec qui je veux comparer en série et en parallèle des vitesses.
import threading
import Queue
import time
import math
def sinFunc(offset, n):
result = []
for i in range(n):
result.append(math.sin(offset + i * i))
return result
def timeSerial(k, n):
t1 = time.time()
answers = []
for i in range(k):
answers.append(sinFunc(i, n))
t2 = time.time()
print "Serial time elapsed: %f" % (t2-t1)
class Worker(threading.Thread):
def __init__(self, queue, name):
self.__queue = queue
threading.Thread.__init__(self)
self.name = name
def process(self, item):
offset, n = item
self.__queue.put(sinFunc(offset, n))
self.__queue.task_done()
self.__queue.task_done()
def run(self):
while 1:
item = self.__queue.get()
if item is None:
self.__queue.task_done()
break
self.process(item)
def timeParallel(k, n, numThreads):
t1 = time.time()
queue = Queue.Queue(0)
for i in range(k):
queue.put((i, n))
for i in range(numThreads):
queue.put(None)
for i in range(numThreads):
Worker(queue, i).start()
queue.join()
t2 = time.time()
print "Serial time elapsed: %f" % (t2-t1)
if __name__ == '__main__':
n = 100000
k = 100
numThreads = 10
timeSerial(k, n)
timeParallel(k, n, numThreads)
#Serial time elapsed: 2.350883
#Serial time elapsed: 2.843030
Quelqu'un peut m'expliquer ce qu'il se passe? J'ai l'habitude de C++, et une version similaire de ce module voit le speed-up, nous nous attendrions.
Les Threads ne sont pas de la magie des appareils que vous ajoutez à l'application et il ira plus vite. L'esprit le coût de fabrication d'un fil est pas négligeable, par exemple, généralement de 1 MO d'Espace d'adressage Virtuel est utilisé seulement à la création.
Peut-être, mais ce n'est pas la question ici. L'OP est en cours d'exécution la tête la première dans le GIL, un problème est généralement résolu en utilisant le
Peut-être, mais ce n'est pas la question ici. L'OP est en cours d'exécution la tête la première dans le GIL, un problème est généralement résolu en utilisant le
multiprocessing
module ou à l'aide de Stackless Python au lieu de la valeur par défaut Disponible interprète.
OriginalL'auteur andyInCambridge | 2012-05-28
Vous devez vous connecter pour publier un commentaire.
D'autres réponses ont évoqué la question de la GIL étant le problème dans disponible. Mais j'ai senti qu'il y avait un peu de manque d'informations. Cela vous causera des problèmes de performances dans les situations où le code que vous sont en cours d'exécution dans les threads CPU est lié. Dans votre cas là, oui fait beaucoup de calculs dans les threads va probablement considérablement les performances dégradées.
Mais, si vous faisiez quelque chose qui était plus IO liées, telles que la lecture à partir de nombreux supports d'une application réseau, ou l'appel à des sous-processus, vous pouvez obtenir des augmentations de rendement de threads. Un exemple simple pour votre code ci-dessus serait d'ajouter un stupidement simple appel à la coque:
Que l'appel puisse être quelque chose de réel, comme en attente sur le système de fichiers. Mais vous pouvez voir que dans cet exemple, le filetage va commencer à se révéler bénéfique, comme le GIL peut être libéré lorsque le thread est en attente sur IO et autres threads continue. Même ainsi, il est encore un endroit doux pour lorsque plusieurs threads commencent à devenir annulé par la surcharge de la création d'eux et de les synchroniser.
Pour CPU, de code, d'utiliser multitraitement
De l'article: http://www.informit.com/articles/article.aspx?p=1850445&seqNum=9
Question similaire références à propos des threads vs processus:
https://stackoverflow.com/a/1227204/496445
https://stackoverflow.com/a/990436/496445
Oh, et un lien vers stackless (stackless.com) pourrait être utile!
OriginalL'auteur jdi
Python a un grave problème de thread. Fondamentalement, l'ajout de threads d'une application Python presque toujours ne parvient pas à le rendre plus rapide, et parfois, il est plus lent.
Cela est dû à la Mondial Interprète De Verrouillage, ou GIL.
Voici post de blog qui comprend un exposé sur le sujet.
Une façon de contourner cette limitation est d'utiliser les processus au lieu de threads; ceci est rendu plus facile par la multitraitement module.
Je comprends le GIL question. Je dis que si le travail effectué dans les filets IO est lié, alors il conviendra à une tige filetée qui approche, car le GIL peut libérer souvent. Et je faisais allusion à une couverture python filetage déclaration.
Oui il y a des problèmes. Cependant, est-ce à dire threads "presque toujours" mal, de même qu'une utilisation judicieuse de l'I/O-lié fils?
Ce n'est pas Python spécifique, il est Disponible spécifiques.
"l'ajout de threads d'une application Python presque toujours ne parvient pas à le rendre plus rapide, et parfois, il est plus lent" comme une déclaration générale à la question est extrêmement trompeuse ou même faux. Le filetage est utile pour l'introduction de la concurrence. Sans concurrence, de nombreuses applications ne peuvent pas être conçu dans un utilisable. Par conséquent, le filetage permet aux applications de fonctionner du tout. Dans la plupart des cas, il n'est pas question de rendre l'application plus rapide.
OriginalL'auteur cha0site
Python bibliothèques écrites en C peut obtenir/libération de la Global Interprète de Verrouillage (GIL). Ceux qui n'utilisent pas des objets Python peut libérer de la GIL, de sorte que les autres threads peuvent obtenir un coup d'oeil, mais je crois que la bibliothèque de mathématiques utilise Python Objets de tous les temps, de manière efficace des mathématiques.le péché est sérialisé. Depuis de verrouillage/déverrouillage est un rétroprojecteur, il n'est pas inhabituel pour Python fils à être plus lent que sur les processus.
OriginalL'auteur cdarke