IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Streaming de données vers disque externe


Sujet :

C

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 60
    Points : 47
    Points
    47
    Par défaut Streaming de données vers disque externe
    Bonjour,

    J'aurais aimé avoir quelques avis. Est il possible de transférer les données d'un appareil sans passer par la mémoire Windows, c'est à dire sans faire une allocation mémoire classique !? En gros, créer un flux de données qui parte de la carte d'acquisition et qui aille directement dans le disque dur en by-passant la ram de l'OS... càd faire du streaming. En fait, je voudrais juste faire une allocation mémoire disque dur pour que ça parte directement dans le disque...au lieu de faire une allocation mémoire "windows"...

    Je m'explique...je récupère via une carte d'acquisition un signal qui se répète 4000 fois par seconde (4KHz), je récupère les 10 000 premiers points sur ses 80 000 points de période qu'il contient, avec une fréquence d'échantillonnage de 300 millions d'échantillons par seconde, acquisitions que j'aimerais enregistré sur un disque dur externe (reliée en PCI express) en temps réel, dans des fichiers binaires...ou autres du moment que je puisse les relire et qu'ils prennent le moins de place possible...

    Pour ça, j'alloue de la mémoire de la façon suivante en fonction de la taille de mes données (méthode qui a priori n'est pas bonne) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    // Alloue de la mémoire
    waveformPtr_session1 = (void*) malloc (LengthDataType * actualRecordLength_session1 * numWaveform_session1);
    et je récupère les données dans la mémoire de la carte via une fonction spécifique du driver de l'appareil

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    niScope_FetchBinary8 (sessions[0], channelListSession1, timeout, actualRecordLength_session1, (ViInt8*) waveformPtr_session1, wfmInfoPtr_session1);
    Tout se passe dans le pointeur waveformPtr_session1, je lui alloue une quantité de mémoire dans windows comme on peut le voir dans le code au dessus et ensuite je récupère avec ce pointeur les données (1 échantillon = 1 octet donc 10 Ko de données par itération) via la fonction fetch qui est dans une boucle (10 000 pts à chaque itération). En gros, je récupère les données, j'enregistre dans le fichier et je boucle jusqu'au stop. Pour gérer tout ça, j'ai créé deux threads, un pour l'acquisition et un pour l'écriture dans le fichier que je gère avec des sémaphores et un mutex.

    C'est trop lent, je perds des données, je passe par la mémoire Windows au lieu d'écrire directement dans le disk externe relié en PCI express. Même quand je supprime la partie écriture dans le fichier, ça perd des données. Je ne respecte pas le principe du streaming développé dans ce lien, ça doit être la cause de mon problème :

    https://www.ni.com/fr-fr/innovations...from-disk.html

    Implementing streaming from the instrument, through the controller, and onto hard disk increases the available memory of the instrument from megabytes to terabytes. By utilizing the high-bandwidth PXI and PXIe bus architectures, data can stream to and from hard disk at a rate high enough to support the instrumentation. This means that oscilloscopes can acquire data and store it directly to disk, while arbitrary waveform generators can pull data directly from disk, bypassing the previously-limiting onboard memory.
    Il faut donc que je trouve une solution pour remplacer

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    waveformPtr_session1 = (void*) malloc (LengthDataType * actualRecordLength_session1 * numWaveform_session1);
    par quelquechose qui enverrait directement les données dans le disque dur externe de 10To...ce qui serait équivalent à passer à une carte de 1Go de RAM (qui se remplie en quelques secondes) à 10To de RAM, soit plusieurs heures d'enregistrements...

    J'ai fait quelques recherches qui m'ont dirigées vers le FileMapping, la mémoire virtuelle, etc... encore flou pour moi pour le moment,...la bonne piste selon vous !? J'hésite à m'engager sur ces pistes...

    Si des personnes savent écrire les données d'un appareil dans un disque dur sans passer par la mémoire Windows ou qui savent faire du streaming en C, je suis preneur de pistes . Aucun des exemples que j'ai ne traite du streaming et pas grand chose, voir rien en C dans mes recherches et le constructeur des cartes d'acquisition ne donne pas d'info pour le faire en C, en gros, il faut passer à la caisse et acheter leur solution, leur logiciel américain LABview en langage G, mais ça doit se faire en C !

    Désolé si je ne suis pas clair mais fin de journée + casse tête , je ne suis plus très frais en écrivant ce post...!

    PS : je suis sous visual C 2008

    Bonne semaine à tout le monde.

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 60
    Points : 47
    Points
    47
    Par défaut
    Je reformule un 2eme post peut être plus clair avec moins d'hardware electronique ;-) :


    Je souhaiterais effectuer un transfert de données d'une carte d'acquisition vers un disque dur externe de 10 To connecté en PXI express. La vitesse de transfert doit pouvoir monter à 300 Mo/sec minimum, 400 Mo pour être tranquille.

    Pour situer cela en ne restant que dans la programmation C, sans trop rentrer dans électronique hardware, voilà comment ça se présente :

    je dispose d'une carte d'acquisition de 1 Go de mémoire et la fonction driver pour retirer les données est la suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    niScope_FetchBinary8 (sessions[0], channelListSession1, timeout, actualRecordLength_session1, (ViInt8*) waveformPtr_session1, wfmInfoPtr_session1);
    quand je fais appel à cette fonction du driver de l'instrument, je récupère les données dans le pointeur "waveformPtr_session1" qui est un argument de sortie de la fonction

    Le problème, c'est que je voudrais envoyer le contenu de ce pointeur dans le disque dur sans passer par la mémoire de windows, donc créé un flux, un streaming. Je travaille sous visual c 2008 sous windows 7, 64 bits.

    Avant d'utiliser ce pointeur, je lui ai fait l'allocation suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    waveformPtr_session1 = (void*) malloc (..........);
    Le problème, c'est que c'est trop lent...je n’atteins pas la vitesse théorique de streaming qui est de 400Mo si ce n'est plus, je perds des données, même en supprimant la partie écriture dans le fichier. Je pense que c'est du au fait que je passe par la mémoire windows avec cette allocation mémoire au lieu d'envoyer directement les données sur le disque dur !?

    Si je bypass la mémoire de l'OS, je dois pouvoir générer un flux qui ne dépendra plus que de la vitesse de ma connexion PXI express entre le disque dur et la carte, un vrai streaming.

    Voilà ce que dit le constructeur de la carte :
    Implementing streaming from the instrument, through the controller, and onto hard disk increases the available memory of the instrument from megabytes to terabytes. By utilizing the high-bandwidth PXI and PXIe bus architectures, data can stream to and from hard disk at a rate high enough to support the instrumentation. This means that oscilloscopes can acquire data and store it directly to disk, while arbitrary waveform generators can pull data directly from disk, bypassing the previously-limiting onboard memory.
    J'ai fait des recherches et j'ai entendu parler de file mapping, pensez vous que cette solution puisse être adaptée pour faire du transfert de datas d'une carte via mon pointeur de datas sur sa mémoire vers le disque !? Je serais tenté de faire un mapping de mon disque dur de 10 To ou découpé en une multitude de fichiers de quelques centaines de Go pour un traitement dans l'autre sens et d'essayer de faire pointer mon pointeur waveformPtr_session1 sur un de ces fichiers mappés du disque dur...!

    Pour le file mapping, j'ai entendu parler de limitation de 2Go pour les fichiers pour du 32 bits.....mais je ne sais pas si ça concerne l'OS ou l'API win 32...! Avez vous une idée sur la meilleure manière (la plus rapide) de transférer ces données en streaming vers un disque !?

    La mémoire de la carte d'1Go se rempli en quelques secondes avec mon acquisition de 300MHz d'échantillonnage. Avec le disque dur de 10 To, ça permet quelques heures d'enregistrements.

    Si vous avez une idée de piste streaming, je suis preneur ;-) , j'ai un doute sur l'option file mapping...mais c'est la seule piste que j'ai, je dois passer par l'API win 32 ( https://docs.microsoft.com/en-us/win...y/file-mapping ) mais j'ai peur d'être limité à des fichiers de 2 Go...

    Merci d'avoir pris la patience de me lire :-)

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Si l'API ne propose que de récupérer les données dans un buffer, je sais pas si tu as d'autres solutions.
    Une API de ce genre devrait aussi proposer une API utilisant un FILE* ou autre structure de fichier pour y écrire directement, sans buffer intermédiaire.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  4. #4
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 859
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 859
    Points : 218 580
    Points
    218 580
    Billets dans le blog
    120
    Par défaut
    Bonjour,

    Pour le file mapping, j'ai entendu parler de limitation de 2Go pour les fichiers pour du 32 bits.....mais je ne sais pas si ça concerne l'OS ou l'API win 32...! Avez vous une idée sur la meilleure manière (la plus rapide) de transférer ces données en streaming vers un disque !?
    Ouep, ça c'est spécifique au 32 bits. Avec un système 64 bits compatible (ou un 64 bits), cela ne devrait pas poser de soucis.

    La documentation MSDN que vous avez donné me semble correcte et à étudier. Avant de voir la documentation, je pensais à un mmap() (oui, c'est du Linux, mais y a un équivalent Windows). En tout cas, la première phrase d'intro est très proche de celle de la MSDN, donc c'est le principe équivalent. Je pense donc que c'est la bonne piste et je doute que vous soyez limité à 2 Go (au pire, vous aurez une option, ou des fonctions spécifiques, pour dépasser cette limite ).
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 60
    Points : 47
    Points
    47
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Si l'API ne propose que de récupérer les données dans un buffer, je sais pas si tu as d'autres solutions.
    Une API de ce genre devrait aussi proposer une API utilisant un FILE* ou autre structure de fichier pour y écrire directement, sans buffer intermédiaire.
    Ils ont fourni une 10aine d'exemples en C, CVI très basique et une documentation de base chm pour faire le driver en C, mais quand il s'agit de faire des choses plus élaborées, ils nous renvoient vers leur logiciel payant LABview en langage G graphique (pas possible de savoir ce qu'il y a dans les blocs) ou autres solutions payantes. Je sais que c'est possible en C, mais leur doc est insuffisante, ce qui ne m'étonne pas trop car ils font une bonne partie de leur chiffre d'affaire dans la formation sur leurs produits et les solutions clés en main comme leurs logiciels, donc ils ont tout intérêt à en mettre le moins possible pour ne pas qu'on puisse développer nous même les softs...


    Citation Envoyé par LittleWhite Voir le message
    Ouep, ça c'est spécifique au 32 bits. Avec un système 64 bits compatible (ou un 64 bits), cela ne devrait pas poser de soucis.

    La documentation MSDN que vous avez donné me semble correcte et à étudier. Avant de voir la documentation, je pensais à un mmap() (oui, c'est du Linux, mais y a un équivalent Windows). En tout cas, la première phrase d'intro est très proche de celle de la MSDN, donc c'est le principe équivalent. Je pense donc que c'est la bonne piste et je doute que vous soyez limité à 2 Go (au pire, vous aurez une option, ou des fonctions spécifiques, pour dépasser cette limite ).
    J'ai commencé à attaquer la doc, je vais partir sur cette piste, on verra bien ce que ça donne ! ça me rassure si je peux dépasser les 2 Go ! Merci.

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 60
    Points : 47
    Points
    47
    Par défaut
    Finalement, j'ai fini par trouver ce que je cherchais, il y a un exemple en CVI qui explique tout, c'est la brique qui me manquait. J'étais sur la bonne piste avec ce que j'avais commencé sur les threads, donc je vais abandonner le file mapping et revenir sur ma première démarche avec cet exemple pour finaliser :

    https://forums.ni.com/t5/Example-Pro...le.language=fr

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XL-2003] Extraction de données fichier .xls vers disque de destination.
    Par BAZO76133 dans le forum Excel
    Réponses: 3
    Dernier message: 28/03/2018, 21h27
  2. Vitesse de transfert PC vers Disque dur externe (USB 2.0 et 3.0)
    Par joffrey575 dans le forum Applications et environnements graphiques
    Réponses: 2
    Dernier message: 23/03/2017, 00h42
  3. copie impossible vers disque dur externe
    Par potope dans le forum Ubuntu
    Réponses: 1
    Dernier message: 24/02/2013, 01h38
  4. Réponses: 6
    Dernier message: 16/09/2008, 21h06
  5. [MySQL] Besoin d'un œil externe pour vérifier mon code (envoi données vers mysql)
    Par cuisto44000 dans le forum PHP & Base de données
    Réponses: 12
    Dernier message: 13/12/2007, 14h48

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo