===== Commit 2016/01/19=====
==== Optimisation FVTM (5 et normalement dernier) ====
Suite à mes commits d'optimisation précédents, le transfert de données peut se faire dans un temps raisonnable.
Par temps raisonnable, je veux dire que la durée du remaillage/transfert/rééquilibrage est à présent du même ordre de grandeur (pour rester modeste) que l'intégration temporelle, en 2D mais aussi en 3D !
=== Exemple 2D ===
Voici deux petits exemples pour vous donner une idée. Si je commence par lancer le test ''backwardExtrusionRemeshing'', qui est 2D, pour différents maillages, j'ai comme évolution :
| Nb éléments | Nb remaillages| Temps total | Temps intégration | Temps transferts | Temps par transfert |
| 80 | 10 | 13.2s | 8.5s | 1.56s | 0.16s |
| 224 | 12 | 21.1s | 12.0s | 4.4s | 0.37s |
| 440 | 13 | 36s | 21s | 8.7s | 0.67s |
| 896 | 15 | 75s | 44s | 20s | 1.33s |
| 1672 | 21 | 185s | 105s | 51s | 2.43s |
| 3584 | 23 | 485s | 283s | 131s | 5.70s |
| 6864 | 25 | 1217s | 744s | 304s | 12.2s |
| 8800 | 28 | 1885s | 1157s | 460s | 16.4s |
{{ :commit:2016:backwardextrusionremeshing2d.png}}
Grâce au graphe, on remarque avec grand plaisir que la courbe d'intégration temporelle est au dessus de celle du transfert de données. Comme quoi, tout peut arriver.
J'ai aussi l'impression que la durée d'une étape de transfert varie linéairement avec le nombre d'éléments, ce qui est plutôt pas mal. Il faudrait vérifier pour des maillages plus gros...
La durée globale de transfert de données augmente, elle, plus que proportionnellement, mais c'est parce que plus on raffine le maillage, plus vite le critère de distorsion de mailles est vérifié et plus souvent on remaille.
=== Exemple 3D ===
A 3D maintenant :
| Nb éléments | Nb remaillages| Temps total | Temps intégration | Temps transferts | Temps par transfert |
| 448 | 1 | 28s | 15s | 7.9s | 7.9s |
| 720 | 1 | 44s | 26s | 11.3s | 11.3s |
| 880 | 1 | 53s | 34s | 14.2s | 14.2s |
| 1792 | 1 | 133s | 90s | 32.6s | 32.6s |
| 2720 | 1 | 197s | 141s | 48s | 48s |
| 4968 | 2 | 788s | 593s | 161s | 80s |
{{ :commit:2016:backwardextrusionremeshing3d.png}}
Les observations sont similaires que dans le cas bidimensionnel. On voit bien ici le saut dans les courbes lorsqu'on passe de un à deux remaillages.
=== Perspectives ===
Continuer à optimiser commence à devenir difficile, car contrairement à la situation initiale, on n'est plus en présence d'une routine nettement plus longue que toutes les autres (''LocalTransferMethod::executeTransfer()''), mais plutôt à un niveau où le temps de calcul est relativement bien réparti entre différentes étapes du transfert de données. Par exemple, le transfert d'un maillage de 3600 éléments tétra prend 2m40 : 1m15 d'initialisation (toDofSet), 25s de couplage et 1m de transfert.
Initialement, cette routine qui était vraiment très longue était parallélisée. Pour y voir clair, je l'avais remise en séquentiel, mais maintenant que je ne souhaite plus optimiser le code je l'ai remise en parallèle.
Le "speedup" est nettement moins bon qu'avant. En effet, vu que cette routine occupait au départ au moins 95% du temps total du transfert, la paralléliser et lancer la simulation sur 4 coeurs réduisait le temps de transfert d'un facteur 4 ou presque. Maintenant que cette routine n'est plus l'étape lente, réaliser le transfert avec 4 coeurs ne réduit même pas sa durée d'un facteur 2. Par exemple, pour backwardExtrusion avec 2720 éléments tétra, un transfert de données se fait en 52 secondes sur un thread et en 31 secondes sur quatre, ce qui donc un "speedup" d'à peine 1.67 au lieu de 4.
Il serait intéressant de voir si d'autres routines ne pourraient pas être parallélisées, mais bon...
==== Résolution du problème de welding en parallèle ====
Nous avions remarqué il y a déjà de nombreux mois, que les cas-tests ''apps.welding'' se lançaient en parallèle même si on leur imposait explicitement de tourner sur un seul thread. Cela posait des problèmes lorsqu'on lançait la batterie, car même en --low le PC répondait très lentement pendant que ces tests-là tournaient.
Je pense avoir finalement trouvé l'origine du problème, qui apparaît en fait quand on utilise l'ALE conjointement avec le remaillage (typiquement, welding).
La première intégration temporelle et le premier transfert de données se font bien sur un seul thread. Seulement, lors du premier restart, avant de recommencer l'intégration temporelle on execute un ''loadFac'', pour recharger la configuration remaillée. Ce ''loadFac'' va notamment appeler la fonction ''AleMethod::initialize()'', qui est parallélisée. Comme à ce stade on est sorti de la première intégration temporelle mais pas encore rentré dans le second, il n'y a pas de ''tbb::task_scheduler_init init(nbt)'' actif. Visiblement, lorsqu'on passe par une boucle parallélisée sans ''scheduler_init'', cette boucle se fait sur le nombre maximal de threads que le PC peut supporter. Une fois ces threads lancés, toutes les prochaines opérations parallèles se font sur tous ces threads, indépendamment des prochains ''scheduler_init''.
Rajouter un ''tbb::task_scheduler_init init(nbt)'' au niveau de l'initialisation de l'ALE résout le problème, on va pouvoir lancer des batteries et continuer à travailler en même temps...
Je trouve personnellement très, très dommage que, lorsqu'il a codé l'ALE, Romain n'ait pas pensé qu'elle pourrait entrer en conflit avec le remaillage... (Le fait que le remaillage a été codé bien après l'ALE n'excuse évidemment rien :-P)
==== Divers ====
A la demande de Luc, renaming des "Chung Hulbert" en "Alpha Generalized".
J'ai aussi modifié les sorties des routines de transfert de données et ma procédure de remaillage, pour essayer que ce qui est affiché à l'écran lorsqu'on lance un test soit plus compréhensible. Des avis sont les bienvenus...
J'ai aussi réorganisé les timers, également du transfert de données et ma procédure de remaillage.
===== Fichiers ajoutés/supprimés =====
A :
R :
===== Tests ajoutés/supprimés =====
A :
R :
--- //[[pjoris@ulg.ac.be|Pierre Joris]] 2016/01/19 //