分支与多线程
代码中有一条快速路径,如下所示:
while(1){
select(fd_set...);
if (fd_isUserspace) {
process_user_packet(fd); // RPC involved
} else { // kernel
process_kernel_packet(fd); // RPC invovled
}
} // while(1)
基本上从一组 fd 中读取一个活动的 fd 并对其进行处理。目前,它是在 if-else 分支中完成的,并且仅在处理完成时返回。我认为我可以通过在 if-else 中使用线程池 (poolSize>=2) 来改进这一点,以便处理 func 立即返回并可以为将来的 fds 再次开始 while 循环。
大概 process_*_packet 会做一些 RPC 工作来进行处理。
我知道将处理作业分派给线程可能会产生一些开销(thread_cond_signal/锁定等),但感觉由于 process_*_packet 可能需要更大量的时间(由于 RPC),也许这是值得的。
想得到一些想法(也许更好的想法),我认为这可能是一个非常普遍的问题,关于如何设计以获得更好的性能。
-谢谢
There's a fast path in the code that looks like this:
while(1){
select(fd_set...);
if (fd_isUserspace) {
process_user_packet(fd); // RPC involved
} else { // kernel
process_kernel_packet(fd); // RPC invovled
}
} // while(1)
Basically reading an active fd from a set of fds and process it. Currently it is done in a if-else branch and only returns when processing completes. I think I can improve this by using a thread-pool (poolSize>=2) within the if-else so that processing func immediately returns and can begin the while loop again for future fds.
Presumably the process_*_packet is gonna do some RPC work for processing.
I'm aware that dispatching the processing job down to a thread may have some overhead (thread_cond_signal/locking etc), but feel like since process_*_packet is probably takes time that is in a larger magnitude (due to RPC) maybe it's worth while.
Would like to get some thoughts (maybe even better idea) and I think this can be a very general question on how the design should be made for better performance.
-Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我最近用Java写了一个线程池(我的并行计算类需要它,我知道有内置的),如果你写得正确,它实际上是相当快的。
如果您使用多个线程,这里的一个巨大优势是:您不再有请求阻塞。您将获得更好的响应时间,因为您可以同时处理多个请求。
如果需要相当长的时间来处理、发送或接收,那么您不需要该数据包必然会堵塞您的管道。
对于某些线程池,您只需执行以下操作:
我们假设 Submit_job 具有签名
以便线程池中的每个线程可以简单地获取它需要处理的函数和参数,并调用 func(args);
我根本不担心派遣工作的费用。如果处理时间超过 1 毫秒(在真正好的实现上可能甚至更短),那么您将是黄金。
I wrote a thread pool in Java recently (Required for my parallel computing class, I know there's the built in one) and if you write it properly, it's actually quite fast.
The one huge advantage here if you use multiple threads: You don't have requests blocking anymore. You'll get better response times because you can handle multiple requests simultaneously.
If one takes a rather long time to process, send, or receive, then you don't need that packet to necessarily clog up your tubes.
With some thread pool, you'd just do:
Where we assume submit_job has the signature
So that each thread in the thread pool can simply grab the function and arguments that it needs to work on, and call func(args);
I wouldn't worry about the cost of dispatching the job at all. If processing takes any more than 1 millisecond (probably even less on really good implementations) then you'll be golden.
只是一个想法,但是如果您放弃
select
并只为每个文件描述符使用一个线程呢?唯一的主要缺点是如果一次出现太多请求,则会产生上下文切换开销,但这可能比延迟更好。优点是在非重载情况下上下文切换较少:一旦文件描述符被解除阻塞,内核就会直接唤醒等待文件描述符的线程,而不是首先唤醒选择线程,然后该线程必须唤醒线程来处理请求。当然,简单性本身就是一个优势……Just an idea, but what if instead you throw out
select
and just use one thread per file descriptor? The only major disadvantage is context switching overhead if too many requests show up at once, but that may be preferable to the latency anyway. The advantage is fewer context switches in the non-overloaded case: the kernel directly wakes up the thread waiting for a file descriptor as soon as it's unblocked, rather than first waking up the select thread which has to then wakeup a thread to process the request. And of course the simplicity of something of an advantage in itself...