【问题标题】:With a single file descriptor, Is there any performance difference between select, poll and epoll and ...?使用单个文件描述符,select,poll和epoll和...之间是否有任何性能差异?
【发布时间】:2011-08-04 14:04:33
【问题描述】:

标题确实说明了一切。

and ...的意思还包括pselect和ppoll..

我正在处理的服务器项目基本上是由多个线程构成的。每个 线程处理一个或多个会话。所有线程都是相同的。协议 负责托管会话的线程。

我正在使用一个内部套接字类来包装东西。兴趣点是一个 checkread 调用,它调用 poll (linux) 或 select (windows)。

总而言之,每个线程当前在单个套接字上调用 poll。据我所知,只有当这个线程正在查看多个套接字时,使用 epoll 才会有好处,比如你会得到一个 HTTP 服务器。在我的情况下,这不是我正在做的事情。并且该类一次只处理一个套接字。

在 epoll 的手册页中有一些关于边缘和电平触发的简短讨论。我不太确定这意味着什么。在套接字类中,我在代码的 windows 部分看到了一个优化,该优化使用 ioctlsocket 和 FIONREAD 来简化选择调用,以检查是否有任何数据。想知道即使在调用时没有完整的 UDP 数据包到达,它是否会返回 > 0。这就是epoll中的边缘触发吗?

在一些基本测试中,我也发现使用 select 和 poll 之间没有明显区别。

我可以看到使用 ppoll 可能会有好处,尽管由于超时的精度更高。有什么想法吗?

是的,我正在尝试优化接收大量数据的会话的吞吐量。服务器比 CPU 更受网络和磁盘限制。

【问题讨论】:

    标签: c++ sockets select epoll


    【解决方案1】:

    epoll 与 select 或 poll 的主要区别在于,epoll 在单线程中运行时可扩展性更好。我不知道这与使用 select 或 poll 使用多线程服务器相比如何。 看看这个http://monkey.org/~provos/libevent/libevent-benchmark2.jpg

    这样做的原因(据我所知)是,当您使用 select 或 poll 时,您必须遍历所有连接的套接字以确定哪些套接字有要读取的数据。当您使用 epoll 时,它会保留一个单独的数组,其中仅包含对要读取数据的套接字的引用。这可以为您节省大量循环周期,并且连接的套接字越多,差异就会越来越明显。

    如果性能成为主要问题,另一件要研究的事情是 io 完成端口(仅限 Windows)和 kqueue(仅限 FreeBSD)。记住 epoll 仅适用于 linux 也很重要。在大多数情况下,选择或投票都可以正常工作。

    在单个文件描述符的情况下,select 和 poll 比 epoll 更高效,因为要简单得多。 (epoll 有一些开销,仅在单个套接字上没有用处)

    【讨论】:

    • 谢谢,这基本上证实了我通过实验发现的。
    • 如果单个文件描述符的数字很大,您不想使用select,因为selectO(max fd number),而pollO(number of fds in the request)
    【解决方案2】:

    根据链接:http://www.intelliproject.net/articles/showArticle/index/io_multiplexing

    如果你只使用一个描述符:

    • select:201 微秒。
    • poll:159 微秒。
    • epoll:176 微秒。

    似乎poll 在这种情况下会是一个更好的解决方案。

    【讨论】:

      【解决方案3】:

      如果您只有一个套接字,那么首先轮询有什么意义?最好的性能不是仅仅使用阻塞读/写吗?

      写。性能,只有一个文件描述符我认为各种方法之间没有太大差异(如果有的话)。如果你真的关心,我想你可以测量,但我发现这对你的程序的整体性能特别重要。

      电平/边沿触发。假设您正在监视一个信号,为简单起见,假设线路中有一些电压。边沿触发意味着当电压超过或低于某个特定限制时触发某些东西。电平触发意味着只要电压超过/低于限制,则认为某物处于触发状态。也就是说,边沿触发在某些事件发生时触发(超过某个阈值),电平触发反映了某个“事物”的状态(在本例中为电压)。

      回到网络编程,边缘触发系统可能是在收到数据包时收到某种信号的系统。如果您不处理该事件,则信号将丢失。水平触发系统 OTOH 类似于询问“缓冲区中是否有数据等待我?”;如果您不处理该事件并再次询问,数据仍然会在那里等着您。

      【讨论】:

      • 通过使用 poll 我可以超时并在同一个线程中做其他工作。当我无事可做以及等待来自网络的数据时,我也可以使用轮询来阻止。我可以创建另一个线程,但这会给共享数据带来其他问题。更多线程 = 更多复杂性,在我的情况下没有任何好处。尝试了很多方法。
      猜你喜欢
      • 1970-01-01
      • 2016-03-22
      • 1970-01-01
      • 2013-07-21
      • 1970-01-01
      • 2018-07-28
      • 1970-01-01
      • 1970-01-01
      • 2016-12-24
      相关资源
      最近更新 更多