0
votes

Comment faire correspondre le temps de traitement avec une heure de réception dans C ++ Multhreading

J'écris une application C ++ dans laquelle je recevrai 4096 octets de données pour toutes les 0,5 secondes. Ceci est traité et la sortie sera envoyée à une autre application. Traitement Chaque ensemble de données prend près de 2 secondes. Voici comment exactement je le fais. Dans ma fonction principale, je reçois les données et je la repousser dans un vecteur. J'ai créé un fil, qui traitera toujours le premier élément et la supprime immédiatement après le traitement. Vous trouverez ci-dessous la simulation de la pièce de réception de mon application. xxx pré>

la sortie de ce code est sortie p>

dans l'image de sortie publiée ici, vous pouvez observer la séquence exacte du traitement. Il ne traite qu'un seul élément pour toutes les 4 insertions. P>

        Note that the reception time of data <<< processing time.


2 commentaires

Les commentaires ne sont pas pour une discussion prolongée; Cette conversation a été déplacé pour discuter .


Est-ce que ma réponse, ou des autres, trier votre problème? Si tel est le cas, envisagez de l'accepter comme votre réponse - en cliquant sur la tick / coche creuse à côté du nombre de vote. Sinon, veuillez dire ce qui ne fonctionnait pas pour que je, ou quelqu'un d'autre, puisse vous aider davantage. Merci. meta.stackexchange. com / questions / 5234 / ...


3 Réponses :


0
votes

comportement non défini

Lorsque vous lisez des données, vous devez verrouiller avant d'obtenir la taille .

occupé à attendre

Vous devriez toujours éviter la boucle serrée qui ne fait rien. Ici si Dustbin est vide, vous allez le vérifier immédiatement contre pour toujours, qui utilisera 100% de ce noyau et ralentira tout le reste, vidangez la batterie de l'ordinateur portable et le rendez plus chaud qu'il ne devrait l'être. très mauvaise idée d'écrire ce code!

apprendre multithreading d'abord

Vous devriez lire un livre ou 2 sur multithreading. Faire du droit multithreading est difficile et presque impossible sans prendre le temps de l'apprendre correctement. C ++ Concurrence en action est fortement recommandé pour la multithreading standard C ++.

variable de condition

Habituellement, vous utiliserez une variable de condition ou une sorte d'événement pour indiquer au filetage du consommateur lorsque des données sont ajoutées de manière à ne pas avoir à se réveiller inutilement pour vérifier si c'est le cas.

Comme vous avez un producteur / consommateur typique, vous devriez pouvoir trouver de nombreuses informations sur la manière de le faire ou des conteneurs spéciaux ou d'autres constructions qui aideront à mettre en œuvre votre code.

sortie

Votre printf et COUT Stuff aura un impact sur les performances et que certains sont à l'intérieur d'une serrure et d'autres non, vous obtiendrez probablement une sortie incorrectement formatée. Si vous avez vraiment besoin de sortie, un troisième thread pourrait être une meilleure option. Dans tous les cas, vous souhaitez minimiser le temps que vous avez un verrou de mise en forme dans un tampon temporaire pourrait aussi être une bonne idée.

Au fait, la sortie standard est relativement lente et il est parfaitement possible qu'il s'agisse même de la raison pour laquelle vous ne pouvez pas traiter rapidement toutes les données.

Taux de traitement

Évidemment, si vous êtes capable de produire 4096 octets de données toutes les 0,5 seconde, mais avez besoin de 2 secondes pour traiter ces données, vous avez un grave problème.

Vous devriez vraiment penser à ce que vous voulez faire dans ce cas avant de poser une question ici car sans ces informations, nous devinons des solutions possibles.

Voici quelques possibilités:

  • ralentir le producteur. De toute évidence, cela ne fonctionne pas si vous obtenez des données en temps réel.
  • Optimisez le consommateur (de meilleurs algorithmes, un meilleur matériel, un parallélisme optimal ...)
  • saute des données

    Évidemment pour les problèmes de performance, vous devez utiliser un profileur pour savoir que vous avez perdu votre temps. Une fois que vous le savez, vous aurez une meilleure idée où vérifier pour améliorer votre code.

    Prendre 2 secondes pour traiter les données est vraiment lente mais nous ne pouvons pas vous aider puisque nous n'avons aucune idée de ce que votre code fait.

    Par exemple, si vous ajoutez les données dans une base de données et que vous ne pouvez pas suivre un suivi, vous pouvez utiliser plusieurs inserts multiples dans une seule commande pour réduire la surcharge de communication avec la base de données sur le réseau.

    Un autre exemple, serait si vous appendez les données à un fichier, vous pouvez utiliser le fichier ouvert et accumuler des données avant de faire chaque écriture.

    conteneur

    Un vecteur ne serait pas un bon choix si vous retirez l'élément de la tête une par une et la taille de la taille deviennent un peu gros (disons plus de 100 petits articles) car chaque autre élément doit être déplacé à chaque fois.

    En plus de changer le conteneur comme suggéré dans un commentaire, une autre possibilité serait d'utiliser 2 vecteurs et de les échanger. De cette façon, vous serez en mesure de réduire le nombre de temps que vous verrouillez le mutex et de traiter de nombreux éléments sans avoir besoin d'un verrou.

    Comment optimiser

    Vous devez accumuler suffisamment de données (disons 30 secondes), arrêter d'accumuler puis tester votre vitesse de traitement avec ces données. Si vous ne pouvez pas traiter ces données en moins d'environ la moitié du temps (15 secondes), vous avez clairement besoin d'améliorer votre vitesse de traitement d'une manière ou d'une autre. Un votre (s) consommateur (s) est suffisamment rapide, vous pourriez alors optimiser la communication du producteur au (s) consommateur (s).

    Vous devez savoir si votre goulot d'étranglement est E / S, une base de données ou quoi et si une partie peut être faite en parallèle.

    Il y a probablement beaucoup d'optimisation qui peut être effectuée dans le code que vous n'avez pas montré ...


1 commentaires

Merci, @ phil1970. Je ne suis pas censé divulguer les détails des algorithmes ni d'autres procédures. Je peux comprendre qu'il est très difficile de donner la meilleure suggestion sans savoir tous les détails complets. Comme vous l'avez mentionné ci-dessus, nous recevons des données en temps réel. Tout ce processus consiste à garantir qu'il n'y a pas de manque dans les données entrantes. Donc, nous ne pouvons pas sauter des données.



0
votes

Si vous ne pouvez pas gérer suffisamment de messages, vous devez laisser tomber quelques-uns.

Utilisez un Tampon circulaire d'une taille fixe.

Puis si le fournisseur est plus rapide que le consommateur, les entrées plus anciennes seront écrasées.

Si vous ne pouvez pas sauter des données et que vous ne pouvez pas le traiter assez rapidement, vous êtes condamné.


0 commentaires

0
votes

Créer deux Const code> Variables, NBUFFERS et NTrthreads, faites-les à la fois 8 au départ si vous avez 16 noyaux et votre traitement est trop lent. Jouez avec ces valeurs plus tard.

Créez des tampons de données NBUFFERS, chacun suffisamment grand pour contenir 4096 échantillons, dans la pratique, il suffit de créer un seul gros tampon et de faire des compensations pour la diviser. P>

Démarrer NTrthreads . Ils attendront chacun de manière continue à être informé de la mémoire tampon à traiter, puis ils le traiteront et attendront à nouveau pour un autre tampon. P>

dans votre programme principal, entrez dans une boucle, recevez des données. Recevez les 4096 premiers échantillons dans le premier tampon et informez le premier fil. Recevez les seconde échantillons 4096 dans le deuxième tampon et avertir le deuxième thread. P>

buffer = (buffer + 1) % NBUFFERS
thread = (thread + 1) % NTHREADS


1 commentaires

Merci, @mark Setchell pour l'idée, je vais l'essayer et vous le faire savoir.