2010-10-12 20 views
5

Tengo una aplicación C# .NET que necesita informar de 4000 a 40,000 dispositivos conectados para realizar una tarea al mismo tiempo (o lo más simultanea posible).Creando miles de subprocesos rápidamente y ejecutándolos casi simultáneamente

La aplicación funciona bien; sin embargo, no estoy satisfecho con el rendimiento. En un mundo perfecto, tan pronto como envíe el comando me gustaría ver que todos los dispositivos respondan simultáneamente. Sin embargo, parece haber una demora ya que todos los hilos que he creado giran y realizan la tarea.

He utilizado .NET 4.0 ThreadPool, he creado mi propia solución usando hilos personalizados e incluso he modificado el ThreadPool existente para permitir que se ejecuten más hilos a la vez.

Todavía quiero un mejor rendimiento y es por eso que estoy aquí. ¿Algunas ideas? ¿Comentarios? ¿Sugerencia? Gracias.

-Shaun

quiero añadir que la aplicación notifica estos 'dispositivos conectados' que necesitan para ir a escuchar para el audio en una dirección de multidifusión.

+4

¿Qué tipo de red es esta? está enviando a través de una multidifusión UDP una opción? –

+1

Sí, indicando a miles de dispositivos que vayan a escuchar audio en una dirección de multidifusión. –

+1

¿Tiene de 4,000 a 40,000 CPU/núcleos? Si lo hace, entonces puede ejecutar todos los hilos al mismo tiempo ... pero si puede multidifundir en UDP, entonces ¿por qué molestarse con los hilos? – Kiril

Respuesta

13

Un procesador de doble núcleo Hyperhreaded PUEDE ser capaz de ejecutar 4 hilos simultáneamente, dependiendo de lo que esté haciendo el hilo (sin contención en IO o acceso a la memoria, etc.). Un hyperthread quad-core quizás 8. Pero 40K simplemente no puede suceder físicamente.

Si quiere al mismo tiempo que simultáneos, es mejor que haga girar tantos hilos como la computadora tenga núcleos libres y que cada thread se desconecte de las notificaciones y luego termine. Te desharás de un montón de cambios de contexto de esta manera.

O, busque en otro lado. Como se recomendó SB en los comentarios, use una multidifusión UDP para notificar a las máquinas de escucha que deben hacer algo.

+2

Te daría otro +1 por sugerir un límite de hilo, si pudiera. – Randolpho

11

Usted no puede ejecutar 4000 hilos simultáneamente, y mucho menos 40k. En el mejor de los casos, en una caja de escritorio con hyperthreading, puede obtener hasta 8 procesos simultáneos (esto supone un núcleo cuádruple). Los hilos son pseudo-paralelos, y eso ni siquiera está profundizando en los problemas de contención del bus.

Si absolutamente necesita simultaneidad para dispositivos de 40k, desea alguna forma de sincronización de hardware.

+5

Y estaría dispuesto a apostar que cualquier sistema de sincronización de hardware que pueda ejecutar 40k nodos simultáneamente será súper caro. – Randolpho

+1

Apreciar tu respuesta. Me gustaría pensar que esto es posible; sin embargo, solo porque creo que he visto algunas aplicaciones hacerlo. Dicho esto, tal vez fue basado en hardware como dijiste. Gracias. –

3

La sobrecarga de crear miles de subprocesos es (muy) significativa; Buscaría una solución alternativa. Esto suena como un trabajo para IO asíncrono: su computadora presumiblemente solo tiene una conexión de red, por lo que no se puede enviar más de un mensaje a la vez. ¡Los hilos no pueden mejorar en esto!

2

¿Estoy en lo cierto al adivinar que está utilizando una API síncrona en su dispositivo, por lo que debe ejecutarse en un hilo? ¿La API tiene una versión asincrónica de la llamada? Si la API del dispositivo realmente puede soportar 40k + dispositivos, entonces debería. También debe tener un control interno de los identificadores de espera (o equivalentes) necesarios para sincronizar los datos de retorno para la devolución de llamada. Esto no es algo que pueda manejar en el lado de la aplicación del cliente; no tiene suficiente visibilidad de la implementación subyacente de la API del dispositivo para saber cómo paralelizar las tareas. Como habrás descubierto, crear subprocesos de 40k con llamadas de bloqueo no sirve.

1

Debería hacer async IO a los dispositivos. Esto es muy eficiente y usa un conjunto diferente (más grande) de hilos para manejar parte del trabajo. Ciertamente, los dispositivos recibirán los comandos mucho más rápido.El grupo de subprocesos IO manejará las respuestas (si las hay)

4

Parece que tiene cierto control sobre qué software se ejecuta en cada dispositivo. En ese caso, podría consultar el uso de HPC y diseñar sus dispositivos (nodos) jerárquicamente y/o usar MPI para ejecutar sus procesos remotos.

Para el ejemplo de jerarquía: designe, por ejemplo, 8 nodos como maestros primarios, nuevamente con 8 nodos esclavos, cada esclavo también puede actuar como maestro con 8 esclavos (puede necesitar mirar un algoritmo de suscripción automatizado para hacerlo) . Tendrá una jerarquía de 6 de profundidad para cubrir 40,000 nodos. Cada maestro tiene una pequeña porción de código que funciona continuamente esperando que las instrucciones pasen a los esclavos.

Todo lo que debe hacer es pasar la instrucción a los 8 maestros principales y su instrucción se propagará al 'clúster' en el cable de forma asíncrona por los maestros. La instrucción solo se debe pasar un máximo de 5 veces, y por lo tanto se propagará v-rápidamente.

Alternativamente (o en conjunción) podría mirar MPI, que es una solución fuera de lo común. Existen algunas implementaciones de C# establecidas.

+0

Analizaré esto. Gracias. –

1

Siempre divertido con estos viejos.

1mb por hilo significa que necesita 4-40 gb solo en RAM mínimo, y 4k-40k núcleos. y el hecho de que tienes una red para enviarlo.

Significa que se sincronizará en algún lugar en el camino, en el conmutador/enrutador más cercano (la mayor parte probablemente incluso en su tarjeta de red, si puede obtener todos los paquetes al mismo tiempo, y logró enviarlo sin guardarlo en caché o morir en ti). Lo que significa simplemente que todo el trabajo multi-threading fue en vano, ya que no alcanzará los puntos finales simultáneamente.

Piense en tomar una carretera de 40'000 y colocar 40'000 automóviles en ella, asegúrese de que todos lleguen al mismo punto en la carretera al mismo tiempo, pero luego salen de la carretera y se van a casa. Todos llegan a casa en diferentes momentos, incluso si comenzaron a conducir en la carretera de 40k en el mismo punto y hora.

Simplemente, no puedes, vencer al mundo físico (aún ...).

Cuestiones relacionadas