2008-12-06 14 views
0

Je suis actuellement en train de retravailler notre code propriétaire d'enrobage de douilles pour utiliser boost asio afin qu'il puisse effectuer une partie de la levée de charges lourdes pour nous. La partie la plus complexe de notre code existant est peut-être le code de gestion de multidiffusion. Le code permet à nos serveurs de niveau intermédiaire (dont il y en a plusieurs dans un système) d'envoyer des multidiffusions à des boîtes client, qui les utilisent pour présenter des mises à jour aux utilisateurs du système.Existe-t-il une "bonne" façon de traiter les multicasts de réassemblage à partir de plusieurs sources?

La raison pour laquelle le code est complexe et sujet aux erreurs est qu'il utilise un certain nombre de tampons bruts pour réassembler les flux de multidiffusion selon leur provenance. Il semble que même avec Boost.Asio, je vais devoir faire face à ce même problème, alors avant que je ne sois coincé, j'ai pensé que ça valait la peine de demander comment d'autres personnes ont fait face à cette situation.

Cela semble être un cas d'utilisation très courant. Est-ce qu'il y a quelque chose qui peut m'aider à faire ce travail sans le code que j'ai maintenant? Ou existe-t-il un modèle C++ établi (Boost ou autre) capable de faire ce genre de travail? De toute évidence, je pourrais me faciliter la tâche et utiliser des conteneurs STL pour mettre en mémoire tampon les paquets au lieu des tableaux bruts, mais ce code doit être très performant. Sur les grandes installations, il y a un grand nombre de paquets qui volent autour et il doit répondre le plus près possible du temps réel.

Merci d'avance pour toute réflexion à ce sujet.

Jamie

Répondre

2

Il ne semble pas que vous avez donné assez d'informations pour obtenir des réponses détaillées, mais il y a quelques conseils généraux à considérer pour le traitement en temps réel des données de multidiffusion. Si vous utilisez la multidiffusion UDP brute, vous effectuez probablement une sorte de séquençage de protocole dans l'espace utilisateur afin de gérer les paquets perdus ou dupliqués. Quelles que soient les optimisations que vous voulez faire, résister à la tentation pour casser la superposition entre votre application et votre couche de protocole.

  • std::vector, dans la plupart des cas, est identique à un tampon de caractères brut alloué dynamiquement. Ne pas hésiter à l'utiliser juste parce que c'est une couche d'abstraction. Il y a deux cas où vous devriez éviter, cependant:
    • Si vous pouvez vous en sortir avec des tampons statiquement alloués
    • Si vous devez transférer en aval la propriété du tampon (bien que si vous concevez carefuly, swap() peut être suffisant)
  • La préallocation est votre ami. Si vous pouvez avoir un ensemble de tampons disponibles pour l'utilisation lorsque les données arrivent, vous pouvez supprimer la plupart des allocations dynamiques du chemin d'exécution rapide.
  • Réduire au minimum les copies de mémoire. Si vous pouvez traiter des données dans une seule pile d'appels, vous avez la possibilité d'éviter les copies. Si vous devez transmettre des données à un thread différent, vous devrez peut-être copier des données.
  • Si votre application peut gérer des tampons groupés (plutôt que d'agréger toutes les données dans un seul tampon), consultez writev et readv. Je ne crois pas que toute solution en conserve résoudra vos problèmes. Boost ASIO, libevent, etc. prendront tous en charge les abstractions de socket pour vous, mais ce que vous faites avec vos données reste sous votre responsabilité, une fois qu'elles ont été livrées.