Question

le code que je traite a des boucles comme suit:

bistar = zeros(numdims,numcases); 
parfor hh=1:nt       
  bistar = bistar +  A(:,:,hh)*data(:,:,hh+1)' ;
end   

pour les petits nt (10).

Après synchronisation, il est en fait 100 fois plus lent que d'utiliser la boucle régulière !!! Je sais que parfor peut faire des sommes parallèles, donc je ne sais pas pourquoi cela ne fonctionne pas.

Je lance

matlabpool

avec les hors-the-box configurations avant d'exécuter mon code.

Je suis relativement nouveau à Matlab, et vient de commencer à utiliser les fonctions parallèles, alors s'il vous plaît ne présumez pas que je ne suis pas en train de faire quelque chose de stupide.

Merci!

PS:. J'exécute le code sur un quad core donc j'attendre à voir quelques améliorations

Était-ce utile?

La solution

Faire le partitionnement et le regroupement des résultats (frais généraux en répartissant le travail et la collecte des résultats des plusieurs fils / noyaux) est élevé pour les petites valeurs de nt. Ceci est normal, vous ne les données de partition pour des tâches simples qui peuvent être exécutées rapidement dans une boucle simple.

Effectuez toujours quelque chose de difficile dans la boucle qui vaut la tête de partitionnement. Voici une belle introduction à la programmation parallèle .

Les fils proviennent d'un pool de threads de sorte que la tête de créer les fils ne devrait pas être là. Mais afin de créer les résultats partiels n matrices de la taille de bistar doit être créé, tous les résultats partiels calculés et tous ces résultats partiels doivent être ajoutés (recombiner). Dans une boucle droite, est avec une forte probabilité fait en place, aucune allocation ont lieu.

La déclaration complète dans l'aide (merci pour votre lien ci-dessous) est:

  

Si le temps de calcul f, g et h est   grand , parfor sera considérablement   plus vite que le correspondant pour   déclaration, même si n est relativement   petit.

Donc, vous voyez qu'ils veulent dire exactement la même chose que ce que je veux dire, les frais généraux pour les petites valeurs de n ne vaut la peine si ce que vous faites dans la boucle est temps / complexe assez longue.

Autres conseils

Parforcomes avec un peu de frais généraux. Ainsi, si nt est vraiment petit, et si le calcul dans la boucle se fait très rapidement (comme une addition), la solution de parfor est plus lente. De plus, si vous exécutez parforon un quad-core, gain de vitesse sera proche de linéaire pour 1-3 noyaux, mais moins si vous utilisez 4 cœurs, depuis le dernier noyau doit également exécuter des processus système.

Par exemple, si parfor vient avec 100ms de tête, et le calcul dans la boucle prend 5 ms, et si l'on suppose que le gain de vitesse est en linéaire à 4 noyaux avec un coefficient de 1 (par exemple au moyen de 4 noyaux rend le calcul 4 fois plus rapide), nt doit être d'environ 30 pour que vous puissiez obtenir un gain de vitesse avec parfor (150ms avec for, 132ms avec parfor). Si vous deviez exécuter seulement 10 itérations, parfor serait plus lent (50ms avec for, 112ms avec parfor).

Vous pouvez calculer les frais généraux sur votre machine en comparant le temps d'exécution avec 1 travailleur vs 0 travailleurs, et vous pouvez estimer le gain de vitesse en faisant un ajustement de ligne à travers les temps d'exécution avec 1 à 4 travailleurs. Ensuite, vous saurez quand il est utile d'utiliser parfor.

En plus de la mauvaise performance en raison de la surcharge de communication (voir d'autres réponses), il y a une autre raison de ne pas utiliser parfor dans ce cas. Tout ce qui se fait dans le parfor dans ce cas utilise intégré multithreading . En supposant que tous les travailleurs sont en cours d'exécution sur le même PC, il n'y a aucun avantage parce qu'un seul appel utilise déjà tous les cœurs de votre processeur.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top