Besoin en microsecondes dans l'application .NET pour limiter le taux de transmission de multidiffusion UDP

StackOverflow https://stackoverflow.com/questions/1631501

Question

J'écris une paire client / serveur de multidiffusion UDP en C # et j'ai besoin d'un délai de l'ordre de 50 à 100 µs (microsecondes) pour limiter le débit de transmission du serveur. Cela permet d'éviter une perte de paquets importante et d'éviter de surcharger les clients liés aux E / S du disque. Ne suggérez pas Thread.Sleep ou Thread.SpinWait. Je ne demanderais pas si j'avais besoin de l'un ou l'autre.

Ma première pensée a été d’utiliser un type de compteur haute performance et de faire une simple boucle while () vérifiant le temps écoulé, mais j’aimerais éviter cela, car on a le sentiment que c’est kludgey. N’at-il pas besoin de lier l’utilisation de la CPU au processus serveur?

Points bonus pour une solution multiplate-forme, c’est-à-dire non spécifique à Windows. Merci d'avance, les gars!

Était-ce utile?

La solution

J'utiliserais le chronomètre , mais il faudrait un boucle

lire this ajouter d'autres extensions au chronomètre, comme ElapsedMicroseconds

ou quelque chose comme ça pourrait fonctionner aussi

System.Diagnostics.Stopwatch.IsHighResolution DOIT être vraie

    static void Main(string[] args)
    {
        Stopwatch sw;
        sw = Stopwatch.StartNew();
        int i = 0;

        while (sw.ElapsedMilliseconds <= 5000)
        {
            if (sw.Elapsed.Ticks % 100 == 0)
            { i++; /* do something*/ }
        }
        sw.Stop();


    }

Autres conseils

Les durées de sommeil très courtes sont généralement optimisées par une boucle de rotation du processeur (semblable à celle que vous décrivez). Vous voulez généralement éviter d'utiliser les appels de minuterie de haute précision, car ils peuvent eux-mêmes prendre du temps et fausser les résultats. Je ne m'inquiéterais pas trop du blocage du processeur sur le serveur pendant des temps d'attente aussi courts.

Je voudrais encapsuler le comportement dans une classe, comme suit:

  • Créez une classe dont le constructeur statique exécute une boucle de rotation pour plusieurs millions d'itérations et enregistre le temps requis. Cela vous donne une idée de la durée d'un cycle de boucle sur le matériel sous-jacent.
  • Calculez une valeur US / itération que vous pouvez utiliser pour calculer des temps de repos arbitraires.
  • Lorsqu'on vous demande de dormir pendant une période donnée, divisez le nombre de dollars US par les valeurs américaines / itération calculées précédemment pour identifier le nombre d'itérations de boucle à effectuer.
  • Faites tourner une boucle while jusqu'à la fin du temps estimé.

J'ai rencontré de telles exigences lorsque j'avais besoin de plus de précision avec mon application de multidiffusion.

J'ai trouvé que la meilleure solution réside dans les minuteries MultiMedia, comme indiqué dans cet exemple .

J'ai utilisé cette implémentation et y ai ajouté un appel asynchrone TPL. Vous devriez consulter mon projet SimpleMulticastAnalyzer pour plus d'informations.

    static void udelay(long us)
    {
        var sw = System.Diagnostics.Stopwatch.StartNew();
        long v = (us * System.Diagnostics.Stopwatch.Frequency )/ 1000000;
        while (sw.ElapsedTicks < v)
        {
        }
    }
    static void Main(string[] args)
    {
        for (int i = 0; i < 100; i++)
        {
            Console.WriteLine("" + i + " " + DateTime.Now.Second + "." + DateTime.Now.Millisecond);
            udelay(1000000);
        }
    }

Avez-vous consulté minuteries multimédia ? Vous pourriez probablement trouver une bibliothèque .NET quelque part qui enveloppe les appels d'API quelque part.

Je découragerais l’utilisation de spin loop car elle consomme et crée un thread bloquant. thread.sleep est préférable, il n'utilise pas les ressources du processeur pendant le sommeil, il coupe simplement le temps. Essayez-le et vous verrez dans le gestionnaire de tâches comment l'utilisation de la CPU augmente avec la boucle de rotation.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top