我们是否有一系列描述符的基准测试,从1到50左右?我看到的大多数基准都是针对大量描述符100s..1000s ......
我目前正在使用带有16个描述符的民意调查,并考虑使用epoll,如果这样可以提高应用程序的速度。
Please advise in 3 scenarios with 16 socket descriptors in the set for poll/epoll:
1. most of the sockets are active...>both should be same performance?
2. half active half idle....what is better here?
3. mostly idle...> clearly epoll is better ?
答案 0 :(得分:2)
我非常怀疑从poll()
切换到epoll()
不会对您的应用程序的性能产生任何影响。当你有许多文件描述符(数百或数千)时,epoll()
的主要优势就会突然出现,其中标准poll()
需要在每次调用时完成更多工作,而epoll()
执行提前设置 - 只要您不更改正在观看的文件描述符集,每次调用都会稍微快一些。但一般来说,这种差异只对很多很多文件描述符都很明显。
请记住,如果您正在观察的文件描述符集非常频繁地更改,epoll()
的主要优点就会丢失,因为您仍需要将新文件描述符传递到内核中。所以,如果你正在处理许多短暂的连接,那么转换它就更不引人注目了。
另一个区别是epoll()
可以边缘触发,其中只有在描述符上发生 new 活动或级别时才会返回调用-triggered ,其中调用返回,而描述符是读/写就绪的。标准poll()
调用始终级别触发。然而,对于大多数人来说,水平触发是他们想要的 - 边缘触发的接口偶尔会有用,但在大多数情况下,它们会导致竞争条件,即数据在读取之后但在进入epoll()
呼叫之前到达套接字。我的建议是远离边缘触发的代码,除非你真的,真的知道你在做什么。
您为epoll()
支付的价格是缺乏可移植性 - poll()
和select()
都是标准的POSIX接口,因此使用它们可以使您的代码更具可移植性。另一方面,epoll()
调用仅适用于Linux。其他一些Unix变种也有自己的等效机制,比如FreeBSD上的kqueue,但在这种情况下你必须为每个平台编写不同的代码。
我的建议是,直到你达到使用许多文件描述符的程度,甚至不用担心epoll()
- 严重的是,你的代码中肯定有很多其他地方可以提高性能无论如何,epoll()
完全有可能对你的用例更快。
如果你确实达到了处理许多连接的阶段,而其余的代码已经非常优化,那么你首先应该考虑像libev这样的跨平台接口,它使用最佳性能呼叫每个特定平台。 performs very well即使您只想支持Linux,也可能比直接使用epoll()
更麻烦。
我没有提到你到目前为止提到的三个场景,因为我不相信它们中的任何一个会对少量文件描述符(如16)执行任何不同的操作。对于大量文件描述符,{{ 1}}应该优于epoll()
,特别是在大多数空闲文件描述符的情况下。如果所有文件描述符始终处于活动状态,则两个调用都需要遍历每个连接以处理它。但是,随着空闲连接的比例增加,poll()
提供了更好的性能,因为它只返回活动连接 - 使用epoll()
,您仍然必须遍历所有内容并且大部分将被跳过,但poll()
1}}只返回您需要处理的那些(最多可以指定的最大限制)。
明确说明(并且仅 与大量连接相关,如上所述):
epoll()
稍微提前。 epoll()
在这里稍好一些。 epoll()
绝对会更好。 修改强>
您可能希望查看来自libevent作者的this graph,并显示处理事件的相对开销,因为文件描述符的数量会发生变化。注意所有线条如何围绕原点汇聚,证明所有机制都能为少量描述符实现相当的性能。