什么是n个文件描述符,之后最好切换到epoll over poll?

时间:2013-07-23 02:12:57

标签: sockets network-programming polling epoll

我们是否有一系列描述符的基准测试,从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 ?

1 个答案:

答案 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}}只返回您需要处理的那些(最多可以指定的最大限制)。

明确说明(并且 与大量连接相关,如上所述):

  1. 大多数套接字都处于活动状态:这两个呼叫大致相当,可能epoll()稍微提前。
  2. 半有效半空闲:希望epoll()在这里稍好一些。
  3. 大部分闲置:希望epoll()绝对会更好。
  4. 修改

    您可能希望查看来自libevent作者的this graph,并显示处理事件的相对开销,因为文件描述符的数量会发生变化。注意所有线条如何围绕原点汇聚,证明所有机制都能为少量描述符实现相当的性能。