Discussions au sujet de NI LabVIEW

annuler
Affichage des résultats de 
Rechercher plutôt 
Vouliez-vous dire : 

Acquisition enregistrement nombreuses données

Bonjour,

 

J'effectue l'acquisition et le traitement de données sur un système.

Deux types d'acquisitions seront effectués :

 -une où le système fonctionnera 500ms

 -une où le système fonctionnera 1H

 

Coté acquisition il dois y avoir une période d'échantillonnage de 10us (micro).

 

Mon Vi d'acquisition effectue trois taches en parallèle :

 -l'acquisition

 -le traitement des données

 -l'enregistrement

 

 

Je rencontre le problème suivant :

Les trois taches communique via des registres à décalages (les files d'attentes étant trop lentes)

Or l'enregistrement des données est environ 100 fois (je me suis trompé dans les commentaires du Vi ci joins le vrai facteur est 100) plus lente que les deux autres tâches (enfin la plus lente des deux).Du coup pour le tir d'une heure il y a trop de données dans le registre à décalage donc le registre bloque la lecture et certains échantillons ne sont pas lus (et c'est mal)

 

Je dois recupérer toutes les données (pas de moyennage ou de supression d'échantillons) car un défaut peut etre de l'ordre de 10us.

 

Actuellement j'utilise un Vi express pour écrire dans mes fichier. Es ce qu'il serais plus intéressant pour moi d'écrire un Vi d'enregistrement de plus bas niveau (je ne pense pas je sais qu'en C il faut déja 1 ms pour écrire une donnée dans un fichier) Il y a t il des solutions qui me garantisse un bon échantillonage sur une durée infinie. (je pensais utiliser des machines sur le réseau mais je pense qu'il existe une solution plus simple)

 

Si vous avez des pistes je suis preneur

 

Coordialement

0 Compliments
Message 1 sur 9
4 345 Visites

Je me suis trompé de Vi je vous envoie le bon

0 Compliments
Message 2 sur 9
4 339 Visites

Bonjour,

 

Il est clair que ton architecture n'est pas adapté à ta tâche, tu devrait considérer avoir une boucle pour chacune des fonctions (surtout acquisition et enregistrement)

Cela permettrait à ta boucle d'écriture de prendre plus de temps sans perturber l'acquisition.

Utilises alors le systême de communication entre les boucles de ton choix. (Je suggère la Queue qui est facile à mettre en place)

Je n'ai pas trouvé d'exemple spécifique à ton application mais en regardant un exemple de Queue tu comprendra comment faire.

 

 

0 Compliments
Message 3 sur 9
4 331 Visites

Bonjour,

 

Comme Didje007, je ne pense pas qu'utiliser ton architecture soit une bonne idée ici. L'idée de ce type d'architecture est bonne à la base mais il faut qu'aucune des tâches mises en parallèle ne retarde les autres puisqu'il n'y a pas de nouvelle itération de la boucle tant que tout le code n'est pas terminé.

 

Dans ton cas, je pense qu'il y a déjà un problème de base avec l'utilisation du VI express. Pou synthétiser, ce VI (et Ecrire dans un fichier tableur) est à bannir quand on veut faire du streaming de donnée car justement c'est très lent : à chaque itération, on ouvre le fichier, on écrit dedans, et on le ferme. Utilise plutôt les VIs de bas niveau (je t'invite à regarder l'aide et les exemples) qui permettent justement d'ouvrir et fermer le fichier en dehors de la boucle.

Côté performances je pense qu'il faut que tu te bases soit sur du binaire (ça peut être compliqué à architecturer) soit sur la solution toute prête de NI qui est le TDMS (qui est du binaire aussi, voir ici). Ce format est assez simple pour gérer différentes voies et groupes de voies.

Autre élément (mais il me semble que tu l'as déjà appliqué), il est plus performant d'enregistrer d'un coup un gros paquet de donnée plutôt que pleins de petits paquets.

 

Je supporte de nouveau Didje sur l'architecture dans le sens où des boucles parallèles seront selon moi plus performantes. Chaque boucle parallèle s'exécute sur un coeur différent, ça a le mérite d'exploiter le CPU comme il faut. Pour communiquer entre ces boucles, il faut utiliser des files d'attentes.

Justement pour revenir sur ce que tu dis, j'ai quand même du mal à imaginer les files d'attentes "lentes". Ne serait-ce pas plutôt dû à la lenteur de tes boucles ? Côté enregistrement ça ne m'étonnerai pas avec le VI express. Côté traitement ... ben justement, as tu fais un benchmark de ton traitement pour savoir combien il te prend ? Regarde l'exemple "Modèle de cadencement (dép données)" qui peut t'aider.

 

Je te demande ça car si tu as de gros volume de données et que ton traitement prend vraiment trop de temps, le buffer de tes files d'attente va exploser et tu vas te trouver en out of memory. Si je me souviens bien, un LabVIEW classique (donc 32 bits) peut utiliser 2Go de mémoire sur un système x86 et 3Go sur un x64. Je te conseille de jeter un oeil au Gestionnaire de tâches Windows pendant l'exécution de ton VI.

 

Pour répondre à ta question d'utiliser des PCs sur le réseau, c'est faisable oui mais c'est à concevoir toi même : créer un programme pour le PC cible, mettre en place un communication (je dirai TCP pour ton cas) etc.

 

 

Voilà tout ce qui me vient à l'esprit pour l'instant et si d'autres vois des erreurs dans ce que je dis, n'éhsitez pas à corriger Smiley clignant de l'œil.

-----
Mat_P
Message 4 sur 9
4 322 Visites

Bonjour,

 


J'ai oublié de préciser que je travaille sur un système monocore.


J'utilise déjà le gestionnaire pendant mon application et je vois que la mémoire et vite saturé.

Le problème viens du fait que les registres sont saturé vous que je rentre 100 données pour chaque donnée vidée

Je suis passé sur un programme avec deux files d'attente (solution antérieur) et en affichant la valeur du nombre d'éléments dans la file

je me rend compte que l'enregistrement n'est pas assez rapide.

 

Je vais donc écrire une fonction de plus bas niveau pour gagner en rapidité d'écriture.

 

Donc pour résumer :

J'ai utilisé le système de file d'attente pour communiquer entre les trois boucles (système équivalent ,dans le cas d'un monocore,à une boucle avec des registres dites moi si je me trompe.)

j'écris avec des fonctions de bas niveaux dans un fichier

 

Résultat

dans le gestionnaire des tâches je vois que l'utilisation de ma mémoire rame augment jusqu'à la saturation, le nombre d'éléments dans ma file d'attente de la boucle calcul à la boucle d'enregistrement augment très vite (et sature ma mémoire)

 

Conclusion :

le problème viens bien du fait que mon contrôleur écrit les données trop lentement par rapport aux données produite un stock se forme et sature ma mémoire.

Comme quelqu'un qui mange des pruneaux si on lui apporte 3 pruneaux par seconde et qu'il ne peut en manger que 2 un stock de pruneaux ce forme et au bout d'un moment le panier déborde.

 

Question:

Es qu'il existe un moyen pour que se soit la boucle d'échantillonnage la moins rapide, ou dis autrement existe t il un notre moyen plus rapide d'enregistrer une donné qu'avec un fichier ?

 

Cordialement

0 Compliments
Message 5 sur 9
4 309 Visites

le fait que vous travaillez sur un monocore n'a rien a voir avec l'architecture à choisir (enfin si mais pas dans cas là).

Un monocore peut tout de meme faire tourner plusieurs boucles. Et c'est même ce qu'on vous recommande.

En séparant les tâches vous devriez arriver à optimiser la mémoire.

Nous ne pouvons voir ce que vous faites dans votre calcul donc il est difficile pour nous de nous prononcer sur l'utilisation mémoire.

En utilisant mes conseils ainsi que ceux de Mat_P vous devriez arriver à quelque chose de fonctionnel.

0 Compliments
Message 6 sur 9
4 303 Visites

Oui le monocore peut faire tourner plusieurs boucle mais il passe de l'une à l'autre à chaque instruction ce qui reviens à la première structure avec une seule boucle (mais bon ce n'est pas le problème ici) Je pense que le problème viens du fait que l'enregistrement de fichier est trop lente je dois recueillir 360 Millions d'échantillon à la fréquence de 100KHz.
Dans le Vi de calcul je ne fais que traiter les valeurs qui arrivent ( à savoir un tableau 1D de waweform de chaque signal de n échantillons) cette action ne consomme qu'une part infime de mémoire vive la plus part étant utilisé par les files d'attentes qui doivent stocker les paquets de données le temps qu'elle soient traitées je vais chercher à obtimiser le temps d'écriture dans le fichier.

0 Compliments
Message 7 sur 9
4 296 Visites

Justement avec une boucle en parrallele vous laisseriez tout le temps nécessaire au vi d'écriture de faire son opération sans pour autant ralentir le vi d'acquisition( qu'il faudra alors cadencer).

Avec deux registres à décalage vous multipliez par deux l'espace mémoire nécessaire pourquoi ne pas avoir une boucel acquisition qui apsse des données à une boucle de traitement et écriture.

 

Selon les opérations faites dans vos vi de calculs il est possible que labview recopie les tableaux et crée donc des copies ce qui augmente encore votre empreinte mémoire.

Aussi lors des deux premières iterations de la boucle votre vi ecrire dans un fichier tourne a vide, il n'a pas encore reçu de données, cela prend un temps non négligeable (ouvrir le fichier ecrire fermer)

 

Essayer mon vi modifié rapidement (il peut necessiter de régler les temps d'execution) et vous verrez surement un fonctionnement différent.

Les performances que vous demandez sont largement ateignables même sur un monocore si une bonne architecture est utilisée.

Une autre amélioration serait d'implémenter les vis d'écriture en bas niveau mais je n'ai pas le temps de vous faire cette modification.

0 Compliments
Message 8 sur 9
4 292 Visites

 

Dans votre fichier la seul différence est que vous avez 2 theards et un time out sur l'attente de données du deuxième thread. Donc vous imposé un maximum d'échantillons par paquet:

période d'échantillonage 1*10^-5

soit 1/10^-5 = 100000 échantillons max par paquets ( sans compter le temps d'execution) si le paquet est plus gros le thread s'arrète.

Il me faut 360M d'échantillons soit 3600 paquets.

Quand je rentre ces valeurs dans le programe modifié vous avez le même problème que moi.

Les éléments s'empilent dans la file d'attente de façon très rapide et finissent par la faire saturer
preuve que le problème viens bien de la vitesse d'exécution de l'écriture dans le fichier.

 

 


Je pense avoir résolue le problème en écrivant mon propre fichier TDMS

j'ai utilisé 3 boucles avec deux files d'attentes

 boucle 1 acquisition
 boucle 2 traitement
 boucle 3 écriture

 

Je n'ai pas mis le Vi de traitement des données avec le Vi d'écriture comme vous l'avez fais car bien que pour l'instant il n'utilise qu'un temps réduit (les calculs étant basiques) Il sera implémenté plus tard des fonctions prenant plus de temps.

J'ai utiliser le TDMS pour écrire mes données qui sont maintenant beaucoup plus rapide. Mes files d'attentes ne se remplisent plus comme avant.Je reste à 2 éléments max lors de mes essais sur plusieurs minutes.

Par contre je suis toujours limité en mémoire par mon affichage. Je ne pourais pas afficher toutes les courbes sur une heure avec une précision de 10us.
Je vais continuer de chercher dans cette voie


Je vous joins le code dans la soirée ou demain si vous avez un peu de temps pour me faire part de vos critiques/remarques/améliorations

0 Compliments
Message 9 sur 9
4 280 Visites