le 04-11-2014 04:52 AM
J'explique en essayant de faire le plus simple possible.
J'ai un vi récursif "toto".
"toto" (qui est le "Main") DOIT obligatoirement être "shared clone reentrant" (ça, ok, je comprends l'évidence)
Dans "toto", j'ai un sous_vi ... (ce sous-vi n'a aucune données "à conserver")
J'ai pacé ce sous-vi en "shared clone" également.
mais ...
je constate que l'ensemble tourne beaucoup plus vite si le sous-vi est en "preallocated clone" (et non en "shared")
en fait ...
le sous-vi peut se trouver dans les 3 modes, "ça tourne" (non-reentrant, shared ou preallocated)
mais la vitesse de l'ensemble n'est pas la même.
sous-vi shared : 28,3sec
sous-vi non-reentrant : 25,5 sec
sous-vi preallocated : 22,1 sec
Question :
si mon sous-vi est "preallocated", pourquoi mon "Main_récursif" est-il plus rapide ?
merci à tous.
le 04-12-2014 05:52 PM
Bonsoir Ouadji,
Impossible de répondre aussi facilement, il nous faut plus de détails.
Combien de fois en parallèle est appellé ce sous vi ? Un petit screenshot ?
Je pense sinon que tu as du lire cet article :
Cordialement,
04-13-2014 02:59 AM - modifié 04-13-2014 03:01 AM
Ce vi est appellé un très grand nombre de fois,
... mais jamais en //.
Il se trouve dans un vi récursif ... mais à chaque récursion, le code de ce vi est terminé (bien évidemment)
et à chaque récursion,c'est normalement un clone diférent qui s'exécute.
Je ne vois aucun réel parallélisme ici.
screenshot : un Main récursif avec environ 15 vi et sous-vi ... difficile pour le screenshot.
04-13-2014 04:00 AM - modifié 04-13-2014 04:07 AM
seule réponse trouvée ...
avec "shared" il y a une "gestion" des clones, et donc des temps d'appel variable et aussi un peu plus long.
avec "preallocated", les clones sont attribués à l'avance, le temps d'appel est donc constant et un peu plus court.
ceci étant dit ...
grosse question existentielle ! ...
comment LV peut-il attribuer des clones "à l'avance" (preallocated) ...
dans un code récursif avec lequel le nombre d'appel du dit vi (et donc le nombre de clones à créer)
est inconnu au départ. ????
le 04-14-2014 04:29 AM
Le compilateur se charge de savoir combien d'instances auront besoin d'être allouées au lancement de l'exécution.
Du coup, on fait mieux qu'en shared parce que pas de réallocation (sauf s'il y en a dans le code lui-même). Et mieux qu'en non-réentrant où on a un mutex sur le sous-VIs et ses ressources partagées 🙂
Eric M. - Senior Software Engineer
Certified LabVIEW Architect - Certified LabVIEW Embedded Systems Developer - Certified LabWindows™/CVI Developer
Neosoft Technologies inc.
04-14-2014 05:36 AM - modifié 04-14-2014 05:38 AM
Le compilateur se charge de savoir combien d'instances auront besoin d'être allouées
difficile dans un vi récursif où la profondeur de récursion dépend des résultats intermédiaires internes au code récursif lui-même. En "preallocated", LV alloue un espace mémoire et un clone du code pour chaque appel présent dans le code. Dans le cas d'un vi résursif (mon cas) ... j'ai 10e+8 exécutions ... pour un et un seul appel physiquement présent dans le code. Je pense donc que LV alloue un et un seul clone ... et ce sera ce même clone qui sera appelé 10e+8 fois, via la récursivité (au même titre que si ce vi_preallocated se trouvait simplement dans une For). Le "petit plus" de rapidité provient (à mon sens) de la non-gestion par le systeme de l'appel lui même (non gestion d'un pool ... caractéristique intrinsèque des clones "preallocated vs les clones "shared"). Ce vi étant appelé un très grand nombre de fois, cette petite différence devient significative. Donc ici, un clone unique, appelé de multiple fois via la récursivité.
Tout ceci n'est pas "la vérité", juste ma façon (pour le moment) de comprendre la chose.
le 04-14-2014 07:20 AM
Je n'ai pas ton code, mais il serait bon de s'assurer de l'unicité de ton clone en mémoire. Pour cela, une méthode simple est d'utiliser la méthode Get VI dependencies (classe VI) en prenant soin de paramétrer l'appel pour qu'il retourne les clones des VIs réentrants.
A l'exécution, tu verras s'il n'y a qu'une instance (un clone) du VI en mémoire 🙂
Du reste, ta théorie sur les pools ne me paraît pas aberrante pour un si grand nombre d'exécutions.
Dans tous les cas, récursif ou non, il ne peut y avoir une infinité de clones en mémoire. Comme l'exécution est partagée entre les clones, et qu'on ne peut exécuter qu'un nombre fini de VIs en parallèle par coeur logique d'un processeur, le nombre de clones est limité 🙂
Eric M. - Senior Software Engineer
Certified LabVIEW Architect - Certified LabVIEW Embedded Systems Developer - Certified LabWindows™/CVI Developer
Neosoft Technologies inc.
04-14-2014 09:14 AM - modifié 04-14-2014 09:15 AM
résultat : (surprise)
avec le sous-vi en question en "preallocated" ... je vois 4 clones.
bon dieu, pourquoi LV crée-t-il 4 clones pour un sous-vi qui ne se trouve dans le code qu'à un seul endroit ?
et... dont le nombre d'appels lui est inconnu.
Pour la petite histoire,
la vitesse la plus rapide est obtenue avec "preallocated + inline".
et là ... il n'y qu'un seul exemplaire du sous-vi en question.