No tengo todas las respuestas. Espero poder arrojar algo de luz sobre ello.
Para simplificar mis declaraciones anteriores sobre los modelos de subprocesos de .NET, solo sepa que Parallel Library usa Tasks, y el TaskScheduler predeterminado para Tasks, usa ThreadPool. Cuanto más alto vayas en la jerarquía (ThreadPool está en la parte inferior), más sobrecarga tendrás al crear los elementos. Esa sobrecarga adicional ciertamente no significa que sea más lenta, pero es bueno saber que está ahí. En última instancia, el rendimiento de su algoritmo en un entorno de subprocesos múltiples se reduce a su diseño. Lo que funciona bien secuencialmente puede no funcionar tan bien en paralelo. Hay demasiados factores involucrados para darle reglas duras y rápidas, cambian dependiendo de lo que está tratando de hacer. Como se trata de solicitudes de red, intentaré dar un pequeño ejemplo.
Déjame decirte que no soy un experto en enchufes, y no sé casi nada sobre Zeroc-Ice. Sé un poco acerca de las operaciones asincrónicas, y aquí es donde realmente te ayudará. Si envía una solicitud síncrona a través de un socket, cuando llameSocket.Receive()
, su subproceso se bloqueará hasta que se reciba una solicitud. Esto no es bueno Su hilo no puede hacer más solicitudes ya que está bloqueado. Usando Socket.Beginxxxxxx (), la solicitud de E / S se realizará y se colocará en la cola IRP para el socket, y su hilo continuará. ¡Esto significa que su hilo podría hacer miles de solicitudes en un bucle sin ningún bloqueo!
Si lo entiendo correctamente, está utilizando llamadas a través de Zeroc-Ice en su código de prueba, en realidad no está tratando de llegar a un punto final http. Si ese es el caso, puedo admitir que no sé cómo funciona Zeroc-Ice. Quisiera, sin embargo, sugieren siguiendo el consejo que aparece aquí , sobre todo la parte: Consider Asynchronous Method Invocation (AMI)
. La página muestra esto:
Al usar AMI, el cliente recupera el hilo de control tan pronto como se ha enviado la invocación (o, si no se puede enviar de inmediato, se ha puesto en cola), permitiendo que el cliente use ese hilo para realizar otro trabajo útil mientras tanto .
Que parece ser el equivalente de lo que describí anteriormente usando sockets .NET. Puede haber otras formas de mejorar el rendimiento al intentar hacer muchos envíos, pero comenzaría aquí o con cualquier otra sugerencia que aparezca en esa página. Ha sido muy vago sobre el diseño de su aplicación, por lo que puedo ser más específico de lo que he sido anteriormente. Solo recuerde, no use más subprocesos de los absolutamente necesarios para obtener lo que necesita, de lo contrario, es probable que su aplicación se ejecute mucho más lentamente de lo que desea.
Algunos ejemplos en pseudocódigo (traté de hacerlo lo más cerca posible del hielo sin que realmente tuviera que aprenderlo):
var iterations = 100000;
for (int i = 0; i < iterations; i++)
{
// The thread blocks here waiting for the response.
// That slows down your loop and you're just wasting
// CPU cycles that could instead be sending/receiving more objects
MyObjectPrx obj = iceComm.stringToProxy("whateverissupposedtogohere");
obj.DoStuff();
}
Una mejor manera:
public interface MyObjectPrx : Ice.ObjectPrx
{
Ice.AsyncResult GetObject(int obj, Ice.AsyncCallback cb, object cookie);
// other functions
}
public static void Finished(Ice.AsyncResult result)
{
MyObjectPrx obj = (MyObjectPrx)result.GetProxy();
obj.DoStuff();
}
static void Main(string[] args)
{
// threaded code...
var iterations = 100000;
for (int i = 0; i < iterations; i++)
{
int num = //whatever
MyObjectPrx prx = //whatever
Ice.AsyncCallback cb = new Ice.AsyncCallback(Finished);
// This function immediately gets called, and the loop continues
// it doesn't wait for a response, it just continually sends out socket
// requests as fast as your CPU can handle them. The response from the
// server will be handled in the callback function when the request
// completes. Hopefully you can see how this is much faster when
// sending sockets. If your server does not use an Async model
// like this, however, it's quite possible that your server won't
// be able to handle the requests
prx.GetObject(num, cb, null);
}
}
Tenga en cuenta que más subprocesos! = Mejor rendimiento al intentar enviar sockets (o realmente hacer algo). Los hilos no son mágicos ya que resolverán automáticamente cualquier problema en el que estés trabajando. Idealmente, desea 1 hilo por núcleo, a menos que un hilo pase mucho tiempo esperando, entonces puede justificar tener más. Ejecutar cada solicitud en su propio hilo es una mala idea, ya que ocurrirán cambios de contexto y desperdicio de recursos. (Si quieres ver todo lo que escribí sobre eso, haz clic en editar y mira las revisiones anteriores de esta publicación. Lo eliminé ya que solo parecía nublar el problema principal en cuestión).
Definitivamente puede realizar estas solicitudes en subprocesos, si desea realizar una gran cantidad de solicitudes por segundo. Sin embargo, no te excedas con la creación del hilo. Encuentre un equilibrio y manténgalo. Obtendrá un mejor rendimiento si utiliza un modelo asincrónico frente a uno sincrónico.
Espero que eso ayude.