C 在轮询中使用未使用的描述符的性能

C 在轮询中使用未使用的描述符的性能,c,linux,performance,sockets,polling,C,Linux,Performance,Sockets,Polling,我有一个用C为Linux编写的应用程序,它必须侦听特定端口上32个TCP套接字的列表。用户可以“屏蔽”这些套接字,以便在解除屏蔽之前不再为它们报告事件 我正在使用非阻塞轮询超时0,因为出于向后兼容性原因,我的应用程序没有线程化。我的问题是,在轮询数组中使用文件描述符时,如果没有要侦听的事件,则会对性能产生影响,而动态地延长和缩小数组可能会很耗时 轮询是否足够智能,可以“跳过”未启用任何事件的描述符,或者我是否会看到它们的存在会对性能造成很大影响 无论哪种方式,假设套接字将以100Hz频率频繁轮询

我有一个用C为Linux编写的应用程序,它必须侦听特定端口上32个TCP套接字的列表。用户可以“屏蔽”这些套接字,以便在解除屏蔽之前不再为它们报告事件

我正在使用非阻塞轮询超时0,因为出于向后兼容性原因,我的应用程序没有线程化。我的问题是,在轮询数组中使用文件描述符时,如果没有要侦听的事件,则会对性能产生影响,而动态地延长和缩小数组可能会很耗时

轮询是否足够智能,可以“跳过”未启用任何事件的描述符,或者我是否会看到它们的存在会对性能造成很大影响

无论哪种方式,假设套接字将以100Hz频率频繁轮询,并且每秒更改一次的频率相对较低,那么这两种方法中哪一种可能获得最佳性能?没有事件的轮询描述符的开销是否会超过每次我进行更改时必须重新生成数组的开销?

看看,没有事件描述符的开销很小。我认为您不会发现只有一个描述符的数组与只有一个非零事件掩码的32个描述符的数组在运行时有任何显著差异

拥有更多的描述符确实意味着内核可能需要在内部分配额外的页面来保存结构。因此,如果您有很多描述符并且丢失了,那么从数组中删除无事件描述符是有意义的

操作struct fds的数组绝对不耗时。我编写了一些测试函数,它们使用两个临时数组——一个是用非零事件掩码的描述符填充的struct fds,提供给poll,另一个是包含指针的函数,这样revents就可以轻松地更新到原始数组——并对它们进行微基准标记。在x86-64 AMD Athlon II X4 640上,在多达1000个描述符的阵列上,每个描述符的函数大约占用5个时钟周期。绝对可以忽略不计的开销,比较一下即使是基本的网络功能也要消耗多少CPU时间

我担心您正遭受过早优化的痛苦。应用程序或库的总体结构将对实现的效率和速度产生更大的影响。因此,与其担心这一点,不如花时间确保您的设计是健壮和合理的

我发现,试图确保数据始终保持流动,不阻塞特定的接收,尽快读取传入的TCP数据包,尝试在相应的数据到达之前做好准备工作,以便数据可以立即被突袭,等等,产生相当好的整体结构


如果您有时间,您可以在分析工作应用程序之后,随时调整细节;因此,将精力集中到真正的瓶颈上。

100Hz从1985年起就不再那么频繁了。你需要测试和测量。我不明白为什么无事件FD会显著降低速度。你不需要仅仅因为你是单线程而使用非阻塞选择,除非你还有其他非网络的事情要做。@EJP不幸的是,情况就是这样,系统也在执行其他任务,我从90年代初开始为实时IPC编写一个模拟器。但是,在尝试了这两种方法之后,您对测量结果提出了一个很好的观点,我只是不确定我得到的任何结果的可靠性或平台依赖性。我正在开发一个与运行代码的系统非常不同的系统。非常感谢您,这是一个极好的答案,完全解决了我的担忧。你们也提出了一个关于过早优化的好观点,我不知何故认为投票会非常耗时,但你们的结果清楚地表明了另一点。再次感谢你的帮助。