http://blog.chinaunix.net/uid-17299695-id-3059078.html

PS:Select和Poll都是水平触发,epoll默认也是水平触发

ET模式仅当状态发生变化的时候才获得通知,这里所谓的状态的变化并不包括缓冲区中还有未处理的数据,也就是说,如果要采用ET模式,需要一直read/write直到出错为止,很多人反映为什么采用ET模式只接收了一部分数据就再也得不到通知了,大多因为这样;而LT模式是只要有数据没有处理就会一直通知下去的.
    LT(level triggered)是缺省的工作方式,并且同时支持block和no-block socket.在这种做法中,内核告诉你一个文件描述符是否就绪了,然后你可以对这个就绪的fd进行IO操作。如果你不作任何操作,内核还是会继续通知你的,所以,这种模式编程出错误可能性要小一点。传统的select/poll都是这种模型的代表.
    ET(edge-triggered)是高速工作方式,只支持no-block socket。在这种模式下,当描述符从未就绪变为就绪时,内核通过epoll告诉你。然后它会假设你知道文件描述符已经就绪,并且不会再为那个文件描述符发送更多的就绪通知,直到你做了某些操作导致那个文件描述符不再为就绪状态了(比如,你在发送,接收或者接收请求,或者发送接收的数据少于一定量时导致了一个EWOULDBLOCK 错误)。但是请注意,如果一直不对这个fd作IO操作(从而导致它再次变成未就绪),内核不会发送更多的通知(only once),不过在TCP协议中,ET模式的加速效用仍需要更多的benchmark确认。

平时大家使用 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 的性能瓶颈需要视应用场景而定,不可一概而论。

[转] 剖析 epoll ET/LT 触发方式的性能差异误解(定性分析)的更多相关文章

  1. 剖析epoll机制

    剖析epoll机制 Linux epoll机制; 写这篇文章的原因是, 上次百度面试被问到一个事件怎么添加到epoll的双向链表中的; 这个问题比较深入, 涉及到内核的实现问题, 今天就来理解一下; ...

  2. 固态硬盘和机械硬盘的比较和SQLSERVER在两种硬盘上的性能差异

    固态硬盘和机械硬盘的比较和SQLSERVER在两种硬盘上的性能差异 在看这篇文章之前可以先看一下下面的文章: SSD小白用户收货!SSD的误区如何解决 这样配会损失性能?实测6种特殊装机方式 听说固态 ...

  3. JMeter下Groovy和BeanShell语言在不同组件中性能差异实践探究

    一般而言JMeter下性能最好的是jar包这类java原生请求,对于JMeter并没有原生支持的请求,一般都会将其直接编译为jar包,然后再JMeter中调用,这样性能最好. 但是有些需求并不适合用j ...

  4. SQL Server ->> DISABLE索引后插入更新数据再REBUILD索引 和 保留索引直接插入更新数据的性能差异

    之前对于“DISABLE索引后插入更新数据再REBUILD索引 和 保留索引直接插入更新数据的性能差异”这两种方法一直认为其实应该差不多,因为无论如何索引最后都需要被维护,只不过是个时间顺序先后的问题 ...

  5. 使用ab.exe监测100个并发/100次请求情况下同步/异步访问数据库的性能差异

    ab.exe介绍 ab.exe是apache server的一个组件,用于监测并发请求,并显示监测数据 具体使用及下载地址请参考:http://www.cnblogs.com/gossip/p/439 ...

  6. 痞子衡嵌入式:对比MbedTLS算法库纯软件实现与i.MXRT上DCP,CAAM硬件加速器实现性能差异

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是MbedTLS算法库纯软件实现与i.MXRT上DCP,CAAM硬件加速器实现性能差异. 近期有 i.MXRT 客户在集成 OTA SBL ...

  7. ArrayList和LinkedList的源码学习,理解两者在插入、删除、和查找的性能差异

    List的使用 List的子类 1). ArrayList 数据结构:数组 2). Vector 数据结构:数组 3). LinkedList 数据结构:循环双向链表 ArrayList .Vecto ...

  8. 比较一下以“反射”和“表达式”执行方法的性能差异

    由于频繁地使用反射会影响性能,所以ASP.NET MVC采用了表达式树的方式来执行目标Action方法.具体来说,ASP.NET MVC会构建一个表达式来体现针对目标Action方法的执行,并且将该表 ...

  9. Ionic中使用Chart.js进行图表展示以及在iOS/Android中的性能差异

    Angular Chart 简介 在之前的文章中介绍了使用 Ionic 开发跨平台(iOS & Android)应用中遇到的一些问题的解决方案. 在更新0.1.3版本的过程中遇到了需要使用图表 ...

随机推荐

  1. pojo和JavaBean的区别

    javabean可以处理业务,pojo不可以. pojo就是get 和set 例如: Student{ id; name; get();... set();...} javabean可以实现业务逻辑 ...

  2. Code::Blocks 的配色方案

    codeblocks的配置文件是default.conf, 在Windows系统下,该文件在C:\Documents and Settings\Administrator\Application Da ...

  3. 抽象数据类型Triplet的C语言实现

    #include <stdio.h> #include <stdlib.h> #define ERROR 0 #define OK 1 typedef int Status; ...

  4. IOS--UILabel的使用方法详细

    IOS-UILabel的使用方法详细   //UILabel的使用 UILabel *oneLabel = [[UILabel alloc] init]; // 最经常使用的 oneLabel.fra ...

  5. [BZOJ 1070] [SCOI2007] 修车 【费用流】

    题目链接:BZOJ - 1070 题目分析 首先想到拆点,把每个技术人员拆成 n 个点,从某个技术人员拆出的第 i 个点,向某辆车连边,表示这是这个技术人员修的倒数第 i 辆车.那么这一次修车对整个答 ...

  6. javascript widget ui mvc

    MVC只是javascript的一个UI模式 JavaScript UI----UI, Template, MVC(View)----Backbone, Angular RequireJS------ ...

  7. Delphi 的各种错误信息(中英文)

    ******************************* * 编 译 错 误 信 息 * ******************************* ';' not allowed befo ...

  8. java学习进制转换之查表法

    10进制转16进制,以及10进制转2进制,还有10进制转8进制,这些转换如果按照常规思路的话,会灰常的麻烦. 我们来看一下 10进制转16进制: 假如这里有一个十进制数字:35,我们的需求就是把这个3 ...

  9. VS2010安装Visual Assist

    Visual Assist X是一款非常好的Microsoft Visual Studio 2005和Visual Studio .NET插件,支持C/C++,C#,ASP,Visual Basic, ...

  10. LA 4726 再看斜率优化

    感觉最近一批解题报告没写,现在慢慢补吧,算是noip前攒攒rp了 首先感到深深的自责,因为之前对斜率优化没有深入的理解,只是记住了一般步骤,并没有完全了解为什么这样做 先就这道题目而言 首先这种序列题 ...