No tengo todas las respuestas. Ojalá pueda arrojar alguna luz sobre él.
Para simplificar mis declaraciones anteriores sobre los modelos de subprocesos de .NET, simplemente sepa que Parallel Library usa Tareas, y el TaskScheduler predeterminado para Tareas, 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 se realiza bien secuencialmente puede no se realiza tan bien en paralelo. Hay demasiados factores involucrados para darle reglas duras y rápidas, cambian según lo que esté tratando de hacer. Ya que estás tratando con solicitudes de red, intentaré y daré un pequeño ejemplo.
Permítame decirle que no soy un experto en enchufes, y no sé casi nada acerca de Zeroc-Ice. Sé algo acerca de las operaciones asíncronas, y aquí es donde realmente te ayudará. Si envía una solicitud sincrónica a través de un socket, cuando llame a Socket.Receive()
, su hilo se bloqueará hasta que se reciba una solicitud. Esto no es bueno Tu hilo no puede hacer más solicitudes ya que está bloqueado. Usando Socket.Beginxxxxxx (), la solicitud de E / S se realizará y se pondrá en la cola de 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 tipo de bloqueo!
Si lo estoy entendiendo correctamente, está usando llamadas a través de Zeroc-Ice en su código de prueba, en realidad no está tratando de llegar a un punto final de http. Si ese es el caso, puedo admitir que no sé cómo funciona Zeroc-Ice. Sin embargo, sugeriría seguir los consejos enumerados aquí , en particular la parte: Consider Asynchronous Method Invocation (AMI)
. La página muestra esto:
Al utilizar AMI, el cliente recupera el hilo de control tan pronto como se ha enviado la invocación (o, si no se puede enviar inmediatamente, se ha puesto en cola), lo que permite al cliente utilizar ese hilo para realizar otro trabajo útil en el tiempo medio.
Lo que parece ser el equivalente de lo que describí anteriormente utilizando sockets .NET. Puede haber otras formas de mejorar el rendimiento al intentar hacer muchos envíos, pero me gustaría comenzar aquí o con cualquier otra sugerencia que aparezca en esa página. Ha sido muy vago en cuanto al 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 que absolutamente necesarios para hacer lo que necesita, de lo contrario, es probable que su aplicación se ejecute mucho más lento de lo que desea.
Algunos ejemplos en pseudocódigo (intenté hacerlo lo más cerca posible del hielo sin que yo 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);
}
}
¡Ten en cuenta que hay más subprocesos! = mejor rendimiento al intentar enviar sockets (o realmente hacer cualquier cosa). Los hilos no son mágicos, ya que resolverán automáticamente cualquier problema en el que estés trabajando. Lo ideal es que desee 1 subproceso por núcleo, a menos que un subproceso pase mucho tiempo esperando, entonces puede justificar tener más. Ejecutar cada solicitud en su propio hilo es una mala idea, ya que se producirán cambios de contexto y un 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 un gran número de solicitudes por segundo. Sin embargo, no exageres con la creación de hilos. Encuentra un equilibrio y quédate con él. Obtendrá un mejor rendimiento si utiliza un modelo asíncrono frente a uno sincrónico.
Espero que eso ayude.