pourquoi n'est pas numpy.mean multithread?
J'ai été la recherche de moyens pour facilement multithread certains de mes simples d'analyse de code car j'avais remarqué numpy c'est seulement à l'aide de l'un de base, malgré le fait qu'il est censé être multithread.
Je sais que numpy est configuré pour plusieurs cœurs, car je peux voir les tests à l'aide de numpy.dot d'utiliser tous mes cœurs, donc, je viens de ré-implémenté dire comme un produit scalaire, et il s'exécute plus rapidement. Est-il une raison de dire ne peut pas exécuter cette rapide sur son propre? J'ai trouver un comportement similaire pour les grandes baies, bien que le ratio est proche de 2 que de 3 montré dans mon exemple.
J'ai lu un tas de posts similaires numpy des problèmes de vitesse, et apparemment son chemin plus compliqué que je ne l'aurais pensé. Aucune information serait utile, je préfère utiliser la moyenne car c'est plus lisible et moins de code, mais j'ai peut passer à point.
In [27]: data = numpy.random.rand(10,10)
In [28]: a = numpy.ones(10)
In [29]: %timeit numpy.dot(data,a)/10.0
100000 loops, best of 3: 4.8 us per loop
In [30]: %timeit numpy.mean(data,axis=1)
100000 loops, best of 3: 14.8 us per loop
In [31]: numpy.dot(data,a)/10.0 - numpy.mean(data,axis=1)
Out[31]:
array([ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
0.00000000e+00, 1.11022302e-16, 0.00000000e+00,
0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
-1.11022302e-16])
source d'informationauteur gggg
Vous devez vous connecter pour publier un commentaire.
Qui dit que c'est censé être multithread?
numpy
est principalement conçu pour être aussi rapide que possible, sur un seul core, et pour être comme parallélisables que possible si vous avez besoin de le faire. Mais vous avez encore à paralléliser.En particulier, vous pouvez fonctionner sur l'indépendance des sous-objets dans le même temps, et la lenteur des opérations de libération de la GIL lorsque c'est possible—bien que "si possible" peut-être pas assez. Aussi,
numpy
objets sont conçus pour être partagé ou transmis entre les processus, aussi facilement que possible, pour faciliter l'aide demultiprocessing
.Il y a quelques méthodes spécialisées qui sont automatiquement mises en parallèle, mais la plupart de la base ne le sont pas. En particulier,
dot
est mis en œuvre sur le dessus de BLAS, si possible, et BLAS est automatiquement parallélisée sur la plupart des plates-formes, maismean
est mis en œuvre dans la plaine du code C.Voir La Programmation parallèle avec numpy et scipy pour plus de détails.
Alors, comment savez-vous quelles sont les méthodes les parallélisée et lesquels ne le sont pas? Et, de ceux qui ne le sont pas, comment savez-vous quels sont ceux qui peuvent être bien manuellement-thread et qui ont besoin d'un traitement multiple?
Il n'y a pas de bonne réponse à cette question. Vous pouvez faire des suppositions éclairées (X semble que c'est probablement mis en œuvre sur le dessus de l'ATLAS, et mon exemplaire de l'ATLAS est implicitement filetée), ou vous pouvez lire la source.
Mais habituellement, la meilleure chose à faire est d'essayer et de tester. Si le code est l'utilisation de 100% d'un seul cœur et 0% des autres, ajouter le manuel de filetage. Si c'est maintenant, en utilisant 100% d'un core et 10% des autres, et à peine en cours d'exécution plus rapide, changer le multithreading de multitraitement. (Heureusement, Python c'est assez facile, surtout si vous utilisez l'Exécuteur des classes de
concurrent.futures
ou la Piscine classes demultiprocessing
. Mais vous avez encore souvent besoin de mettre un peu la pensée en elle, et de tester les coûts relatifs de partage vs passant si vous avez de grands tableaux.)Aussi, comme kwatford points, juste parce que certains de la méthode ne semble pas être implicitement parallèle ne signifie pas qu'il ne sera pas en parallèle dans la prochaine version de numpy, ou la prochaine version de BLAS, ou sur une autre plate-forme, ou même sur une machine avec un peu de trucs différents installé. Donc, être prêt à re-test. Et faire quelque chose comme
my_mean = numpy.mean
et ensuite utilisermy_mean
partout, de sorte que vous pouvez simplement modifier une ligne pourmy_mean = pool_threaded_mean
.Fondamentalement, parce que la bibliothèque BLAS a une optimisation du produit scalaire qu'ils peuvent facilement appeler pour
dot
qui est intrinsèquement parallèle. Ils admettent qu'ils pourraient étendre numpy pour paralléliser les autres opérations, mais a choisi de ne pas aller dans cette voie. Cependant, ils donnent plusieurs conseils sur la façon de paralléliser votre numpy code (en gros, de répartir le travail entre N noyaux (par exemple, N=4), diviser votre tableau en N sous-ensembles et envoyer des tâches pour chaque sous-tableau à sa propre thread, et puis de combiner vos résultats).Voir http://wiki.scipy.org/ParallelProgramming :