MATLAB parfor est plus lente que pour — quel est le problème?
le code que j'ai fais face a des boucles comme suit:
bistar = zeros(numdims,numcases);
parfor hh=1:nt
bistar = bistar + A(:,:,hh)*data(:,:,hh+1)' ;
end
pour les petites nt (10).
Après le calendrier, il est en fait 100 fois plus lent que l'utilisation régulière en boucle!!! Je sais que parfor pouvez le faire en parallèle sommes, donc je ne suis pas sûr de savoir pourquoi cela ne fonctionne pas.
- Je exécuter
matlabpool
avec le dehors-de-le-boîte de configurations avant l'exécution de mon code.
Je suis relativement nouveau à matlab, et juste commencé à utiliser le parallèle fonctionnalités, donc merci de ne pas supposer que je suis de ne pas faire quelque chose de stupide.
Merci!
PS: je suis l'exécution du code sur un quad core donc je m'attends à voir quelques améliorations.
- pouvez vous s'il vous plaît nous dire les valeurs de numdims, numcases et le moment où les chiffres que vous avez découverts? merci.
Vous devez vous connecter pour publier un commentaire.
Faire le partitionnement et de regrouper les résultats généraux de la division du travail et la collecte des résultats à partir de plusieurs threads/carottes) est élevé pour les petites valeurs de
nt
. C'est normal, vous ne serait pas la partition de données pour des tâches simples qui peuvent être exécutées rapidement par une simple boucle.Effectuez toujours quelque chose de difficile à l'intérieur de la boucle qui vaut le partitionnement de frais généraux. Voici une belle introduction à la programmation parallèle.
Les fils viennent à partir d'un pool de threads si bien que la surcharge de créer les threads ne devrait pas être là. Mais pour créer les résultats partiels
n
des matrices de labistar
taille doit être créé, tous les résultats partiels calculés et puis tous ces résultats partiels doivent être ajoutés (recombinaison). En ligne droite de la boucle, c'est avec une grande probabilité effectuée sur place, pas d'allocations de prendre place.La déclaration complète dans l'aide (merci pour le lien ci-dessous) est:
Donc, vous voyez qu'ils signifient exactement la même chose que ce que je veux dire, les frais généraux pour les petites valeurs n est que la valeur de l'effort si ce que vous faites dans la boucle est complexe/temps de consommer suffisamment.
Parfor
est livré avec un peu de surcharge. Ainsi, sint
est vraiment petit, et si le calcul de la boucle se fait très rapidement (comme un plus), leparfor
solution est plus lent. En outre, si vous exécutezparfor
sur un quad-core, un gain de vitesse sera presque linéaire pour 1 à 3 noyaux, mais moins si vous utilisez les 4 cœurs, depuis le dernier noyau doit également exécuter les processus du système.Par exemple, si parfor est livré avec 100ms de surcharge, et le calcul de la boucle de 5ms, et si l'on suppose que le gain de vitesse est linéaire jusqu'à 4 cœurs avec un coefficient de 1 (c'est à dire à l'aide de 4 carottes de fait le calcul à 4 fois plus rapide),
nt
doit être d'environ 30 pour vous d'atteindre un gain de vitesse avecparfor
(150ms avecfor
, 132ms avecparfor
). Si vous avez été à fonctionner seulement 10 itérations,parfor
serait plus lent (50ms avecfor
, 112ms avecparfor
).Vous pouvez calculer les frais généraux sur votre ordinateur en comparant les temps d'exécution avec 1 ouvrier vs 0 travailleurs, et vous pouvez estimer un gain de vitesse par une doublure au niveau du temps d'exécution de 1 à 4 travailleurs. Ensuite, vous saurez quand il est utile d'utiliser
parfor
.En plus de la mauvaise performance à cause de la communication, les frais généraux (voir les autres réponses), il y a une autre raison de ne pas utiliser
parfor
dans ce cas. Tout ce qui est fait dans leparfor
dans ce cas utilise construit-dans le multithreading. En supposant que tous les travailleurs sont en cours d'exécution sur le même ordinateur, il n'y a pas d'avantage, car un seul appel utilise déjà tous les cœurs de votre processeur.