一个关于EPOLLET和EPOLLLT的问题
来源:互联网 发布:淘宝客好做不 编辑:程序博客网 时间:2024/06/06 03:00
觉得此文还不错,收藏以备日后学习。
请教大家一个关于EPOLLET和EPOLLLT的问题
游戏服务器,我们用的是ET方式。
剖析 epoll ET/LT 触发方式的性能差异误解(定性分析)
平时大家使用 epoll 时都知道其事件触发模式有默认的 level-trigger 模式和通过 EPOLLET 启用的 edge-trigger 模式两种。从 epoll 发展历史来看,它刚诞生时只有 edge-trigger 模式,后来因容易产生 race-cond 且不易被开发者理解,又增加了 level-trigger 模式并作为默认处理方式。
二者的差异在于 level-trigger 模式下只要某个 fd 处于 readable/writable 状态,无论什么时候进行 epoll_wait 都会返回该 fd;而 edge-trigger 模式下只有某个 fd 从 unreadable 变为 readable 或从 unwritable 变为 writable 时,epoll_wait 才会返回该 fd。
通常的误区是:level-trigger 模式在 epoll 池中存在大量 fd 时效率要显著低于 edge-trigger 模式。
但从 kernel 代码来看,edge-trigger/level-trigger 模式的处理逻辑几乎完全相同,差别仅在于 level-trigger 模式在 event 发生时不会将其从 ready list 中移除,略为增大了 event 处理过程中 kernel space 中记录数据的大小。
然而,edge-trigger 模式一定要配合 user app 中的 ready list 结构,以便收集已出现 event 的 fd,再通过 round-robin 方式挨个处理,以此避免通信数据量很大时出现忙于处理热点 fd 而导致非热点 fd 饿死的现象。统观 kernel 和 user space,由于 user app 中 ready list 的实现千奇百怪,不一定都经过仔细的推敲优化,因此 edge-trigger 的总内存开销往往还大于 level-trigger 的开销。
一般号称 edge-trigger 模式的优势在于能够减少 epoll 相关系统调用,这话不假,但 user app 里可不是只有 epoll 相关系统调用吧?为了绕过饿死问题,edge-trigger 模式的 user app 要自行进行 read/write 循环处理,这其中增加的系统调用和减少的 epoll 系统调用加起来,有谁能说一定就能明显地快起来呢?
实际上,epoll_wait 的效率是 O(ready fd num) 级别的,因此 edge-trigger 模式的真正优势在于减少了每次 epoll_wait 可能需要返回的 fd 数量,在并发 event 数量极多的情况下能加快 epoll_wait 的处理速度,但别忘了这只是针对 epoll 体系自己而言的提升,与此同时 user app 需要增加复杂的逻辑、花费更多的 cpu/mem 与其配合工作,总体性能收益究竟如何?只有实际测量才知道,无法一概而论。不过,为了降低处理逻辑复杂度,常用的事件处理库大部分都选择了 level-trigger 模式(如 libevent、boost::asio等)
结论:
• epoll 的 edge-trigger 和 level-trigger 模式处理逻辑差异极小,性能测试结果表明常规应用场景 中二者性能差异可以忽略。
• 使用 edge-trigger 的 user app 比使用 level-trigger 的逻辑复杂,出错概率更高。
• edge-trigger 和 level-trigger 的性能差异主要在于 epoll_wait 系统调用的处理速度,是否是 user app 的性能瓶颈需要视应用场景而定,不可一概而论。
欢迎就此话题进行深入调研、讨论!
参考资料:
• linux kernel source:fs/eventpoll.c
• “Comparing and Evaluating epoll, select, and poll Event
Mechanisms”:http://bcr2.uwaterloo.ca/~brecht/papers/getpaper.php?file=ols-2004.pdf
• “Edge-triggered interfaces are too difficult?”:http://lwn.net/Articles/25137/
By QingWu
posted on 2013-02-25 13:05 麒麟子 阅读(3473) 评论(1) 编辑 收藏 引用 所属分类: Programming
原文出处:
http://www.cppblog.com/Leaf/archive/2013/02/25/198061.html
- 一个关于EPOLLET和EPOLLLT的问题
- epoll 的 EPOLLET 和 EPOLLLT
- epoll 的 EPOLLET 和 EPOLLLT
- epoll:EPOLLLT和EPOLLET的区别
- EPOLLLT和EPOLLET
- epoll的EPOLLLT模式和EPOLLET模式比较
- epoll的EPOLLLT模式和EPOLLET模式比较
- epoll模型的EPOLLLT模式和EPOLLET模式比较
- epoll模型的EPOLLLT模式和EPOLLET模式比较
- EPOLLLT——水平触发 EPOLLET——边缘触发区别
- 关于gethostbyname和getaddrinfo的一个问题
- 一个关于编译和inline的问题
- 一个关于wcscpy和wcscpy_s的问题
- 关于||和&&的一个有趣问题
- 关于BadgeView遇到的一个奇怪的问题和解决办法
- 遇到的一个关于 this 和toString()的问题
- 求救,一个关于vb和数据库的问题
- JAVA中关于继承和隐藏的一个另类问题。
- SAE Python 后台1
- 【MyBatis框架】高级映射-一对多查询
- cscope.exe程序的base64文本
- JAVA代理模式--静态代理
- seajs 3.0.0 源码阅读笔记
- 一个关于EPOLLET和EPOLLLT的问题
- Linux守护进程加上发送信号固定模式
- iOS Autolayout 介绍 2 Interface Builder 技巧
- Linux下的tar压缩解压缩命令详解
- python学习——列表生成式
- android中MVP模式(一)
- 华为机试题【13】-wave数组找字母游戏
- iOS学习(二十三)Objective-C 静态vs动态
- NYOJ-阶乘因式分解(一)(二)
评论
# re: 请教大家一个关于EPOLLET和EPOLLLT的问题 2013-02-26 16:14 peakflys
其实这个问题我之前在一篇blog里已经讨论过(http://www.cppblog.com/peakflys/archive/2012/08/26/188344.aspx)
我现在的结论是:ET模式在网络层方面的效率确实比LT要高。
主要表现在:
1、网络IO比较小时,send buffer表现为一直可写,如果网络主循环没有延时操作的话,epoll_wait每次调用都会马上有事件返回,导致不必要的CPU空耗。
2、在网络IO比较大,尤其是连接数比较多的时候,每次epoll_wait调用时LT模式肯定比ET模式多,因为之后需要对ready list 进行遍历处理,如果处理逻辑比较复杂,或者之前反馈的事件数LT比ET多很多的话,这时候效率差异就比较明显了。
还是那句话,ET模式在网络主循环处理的效率肯定比LT模式要高,至于高多少,视具体应用和具体实现。当然ET模式的代价就是增加了网络层的逻辑处理复杂度,必须保证时刻知道fd当前的状态。