Necesita un retraso de microsegundos en la aplicación .NET para acelerar la velocidad de transmisión de multidifusión UDP

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

Pregunta

Estoy escribiendo un par de cliente / servidor de multidifusión UDP en C # y necesito un retraso del orden de 50-100 µs (microsegundos) para reducir la velocidad de transmisión del servidor. Esto ayuda a evitar una pérdida significativa de paquetes y también evita que se sobrecarguen los clientes que están vinculados a E / S de disco. No sugiera Thread.Sleep o Thread.SpinWait. No preguntaría si necesitaba alguno de esos.

Lo primero que pensé fue usar algún tipo de contador de alto rendimiento y hacer un simple bucle while () para verificar el tiempo transcurrido, pero me gustaría evitarlo, ya que se siente muy mal. ¿No vincularía eso también la utilización de la CPU para el proceso del servidor?

Puntos de bonificación para una solución multiplataforma, es decir, no específica de Windows. Gracias de antemano, chicos!

¿Fue útil?

Solución

Usaría cronómetro pero necesitaría un bucle

lea esto para agregar más extensión al cronómetro, como ElapsedMicroseconds

o algo así podría funcionar también

System.Diagnostics.Stopwatch.IsHighResolution DEBE ser cierto

    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();


    }

Otros consejos

Los tiempos de suspensión muy cortos generalmente se logran mejor con un ciclo de giro de la CPU (como el que usted describe). En general, desea evitar el uso de llamadas de temporizador de alta precisión, ya que pueden tomar tiempo y sesgar los resultados. No me preocuparía demasiado la vinculación de la CPU en el servidor para tiempos de espera tan cortos.

Encapsularía el comportamiento en una clase, de la siguiente manera:

  • Cree una clase cuyo constructor estático ejecute un ciclo de rotación durante varios millones de iteraciones y capture cuánto tiempo lleva. Esto le da una idea de cuánto tiempo tomaría un ciclo de ciclo único en el hardware subyacente.
  • Calcule un valor de us / iteración que pueda usar para calcular tiempos de suspensión arbitrarios.
  • Cuando se le pide que duerma durante un período de tiempo particular, divida usS para dormir por el valor de us / iteración previamente calculado para identificar cuántas iteraciones de bucle realizar.
  • Gire con un ciclo while hasta que transcurra el tiempo estimado.

He experimentado con tales requisitos cuando necesitaba más precisión con mi aplicación de multidifusión.

He descubierto que la mejor solución reside en los temporizadores MultiMedia como se ve en este ejemplo .

Utilicé esta implementación y le agregué invocación asíncrona TPL. Debería ver mi SimpleMulticastAnalyzer proyecto para obtener más información.

    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);
        }
    }

¿Ha visto temporizadores multimedia ? Probablemente podría encontrar una biblioteca .NET en algún lugar que envuelva las llamadas API en algún lugar.

Desalentaría el uso de spin loop ya que consume y crea un hilo de bloqueo. thread.sleep es mejor, no usa recursos del procesador durante el sueño, solo corta el tiempo. Pruébelo y verá en el administrador de tareas cómo aumenta el uso de la CPU con el ciclo de giro.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top