我没有所有的答案。希望我能对此有所启发。
为了简化我以前有关.NET线程模型的声明,只需知道Parallel Library使用Tasks,而默认的TaskScheduler for Tasks使用ThreadPool。层次结构越高(线程池位于底部),创建项目时的开销就越大。额外的开销当然并不意味着它会变慢,但是很高兴知道它在那里。最终,算法在多线程环境中的性能取决于其设计。顺序执行良好的结果可能无法并行执行。涉及太多因素,无法为您提供严格的规则,这些规则会根据您要执行的操作而变化。由于您正在处理网络请求,因此我将尝试举一个小例子。
让我指出,我不是套接字专家,而且我对Zeroc-Ice几乎一无所知。我确实了解异步操作,这对您真正有帮助。如果通过套接字发送同步请求,则在调用时Socket.Receive()
,线程将阻塞,直到收到请求为止。不好 您的线程无法再发出请求,因为它已被阻止。使用Socket.Beginxxxxxx(),将发出I / O请求并将其放入套接字的IRP队列中,并且您的线程将继续运行。这意味着,您的线程实际上可以在一个循环中发出数千个请求,而没有任何阻塞!
如果我对您的理解正确,则说明您是在测试代码中使用通过Zeroc-Ice进行的调用,而不是实际尝试访问http端点。如果是这样,我可以承认我不知道Zeroc-Ice的工作原理。不过,我建议您遵循此处列出的建议,尤其是其中的部分:Consider Asynchronous Method Invocation (AMI)
。该页面显示以下内容:
通过使用AMI,客户端可以在发送调用后立即重新获得控制线程(或者,如果无法立即发送,则已经排队),从而允许客户端同时使用该线程执行其他有用的工作。 。
这似乎等效于我上面使用.NET套接字描述的内容。尝试进行大量发送时,可能还有其他提高性能的方法,但是我将从这里开始或从该页面上列出的任何其他建议开始。您对应用程序的设计一直很含糊,所以我可以比上面更具体。请记住,不要使用超出绝对必要数量的线程来完成所需的工作,否则您的应用程序运行速度可能会比所需的慢得多。
伪代码中的一些示例(试图使它尽可能接近冰,而无需我实际学习它):
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();
}
更好的方法:
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);
}
}
请记住,尝试发送套接字(或实际执行任何操作)时,更多的线程!=更好的性能。线程不是魔术,因为它们会自动解决您正在处理的任何问题。理想情况下,您希望每个核心1个线程,除非一个线程花大量时间等待,那么您可以证明拥有更多线程是合理的。在自己的线程中运行每个请求是一个坏主意,因为会发生上下文切换和资源浪费。(如果您想查看我所写的所有内容,请单击“编辑”,然后查看本文的过去修订。我删除了它,因为它似乎笼罩了当前的主要问题。)
如果要每秒发出大量请求,则绝对可以在线程中发出这些请求。但是,不要过度使用线程创建。找到一个平衡并坚持下去。如果使用异步模型而不是同步模型,则将获得更好的性能。
希望对您有所帮助。