首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java NIO选择器最小可能的延迟

Java NIO选择器最小可能的延迟
EN

Stack Overflow用户
提问于 2012-08-23 20:26:37
回答 2查看 3.3K关注 0票数 9

我正在Linux上使用优化的Java选择器(127.0.0.1)进行一些基准测试。

我的测试很简单:

  • 一个程序将一个UDP数据包发送到另一个程序,该程序将其回显给发送方,并计算往返时间。下一个数据包仅在前一个数据包被加到时(返回时)才发送。在执行基准测试之前,将对数百万条消息进行适当的热身。消息有13个字节(不包括UDP头)。

对于往返时间,我得到以下结果:

  • 分钟时间: 13微秒
  • 平均时间: 19微秒
  • 75%百分比:18 567纳米
  • 90%百分比: 18,789纳米
  • 99%百分比:19 184纳米
  • 99.9%百分比:19 264纳米
  • 99.99%百分比:19 310纳米
  • 99.999%百分位数:19 322纳米

但这里的问题是,我正在旋转100万条信息。

如果我只旋转了10条信息,我得到的结果是截然不同的:

  • 分钟时间: 41微秒
  • 平均时间: 160微秒
  • 75%百分比: 150,701纳米
  • 90%百分比:155 274纳米
  • 99%百分比: 159,995纳米
  • 99.9%百分比: 159,995纳米
  • 99.99%百分比: 159,995纳米
  • 99.999%百分位数: 159,995纳米

如果我错了,请纠正我,但是我怀疑一旦我们得到了NIO选择器,那么响应时间就变成了最佳。然而,如果我们发送消息的间隔足够大,我们就会为唤醒选择器而付出代价。

如果我只发送一条信息,我就能得到150到250微米之间的不同次数。

因此,我向社会提出的问题是:

1-是我的最小时间为13微秒,平均19微秒最适合这个往返包测试。看起来我已经打败了ZeroMQ,所以我可能错过了一些东西。从这个基准看来,ZeroMQ在标准内核=> http://www.zeromq.org/results:rt-tests-v031上的平均时间是49微秒(99% )。

当我旋转一条或很少几条信息时,我能做些什么来改善选择器的反应时间吗? 150微米看起来不太好。或者,我应该假设在prod环境中,选择器不是完全正确的?

通过忙碌地围绕selectNow()旋转,我能够获得更好的结果。发送少量数据包比发送多个数据包还要糟糕,但我认为我现在达到了选择器性能的限制。我的研究结果:

  • 发送一个包,我得到一个稳定的65微秒往返时间。
  • 发送两个包,平均得到39微秒的往返时间。
  • 发送10包,我平均得到17微秒往返时间。
  • 发送10,000包我得到大约10,098纳诺往返时间平均。
  • 发送100万包,平均得到9977个nanos往返时间。

结论

  • 因此,看起来UDP数据包往返的物理屏障是平均10微秒,尽管我得到了一些包,使旅行在8微秒(min时间)。
  • 通过忙碌的旋转(谢谢彼得),我能够从平均200微秒提高到平均每包65微秒。
  • 不知道为什么ZeroMQ是慢5倍,而不是那个。(编辑:可能是因为我通过回送在同一台机器上测试这一点,而ZeroMQ使用的是两台不同的机器?)
EN

回答 2

Stack Overflow用户

发布于 2012-08-24 09:39:57

您经常会看到在那里唤醒线程的情况可能非常昂贵,不仅仅是因为线程需要时间才能唤醒,而且线程在缓存和缓存之后的运行速度慢了2-5倍,慢了几十微秒。

我过去避免这种情况的方法是忙着等待。不幸的是,selectNow每次调用它时都会创建一个新集合,即使它是一个空集合。这会产生这么多垃圾,不值得使用。

其中一种方法就是忙着等待非阻塞套接字。这不是很好的扩展,但可以给您提供最低的延迟,因为线程不需要唤醒,并且您运行的代码更有可能在缓存中。如果您也使用线程亲和力,它可以减少您的线程干扰。

我还建议您尽量减少代码锁定,减少垃圾。如果这样做,您可以在Java中有一个进程,该进程在100微秒内90%的时间内向传入的数据包发送响应。这将允许您处理每包在100 Mb,当他们到达(由于带宽限制而间隔145微秒)为一个1GB的连接,你可以得到相当接近。

如果您希望在Java中的同一个框上进行快速进程间通信,您可以考虑使用共享内存来传递小于200 奈米秒的往返延迟(这很难用套接字有效地进行)的消息。如果您只想要一种快速生成日志文件的方法,那么它也会持久化数据,并且非常有用。

票数 4
EN

Stack Overflow用户

发布于 2013-02-16 01:36:15

如果正确调整选择器,则可以在不到2微秒内用Java实现套接字间通信。以下是256字节UDP数据包的单向结果:

代码语言:javascript
复制
Iterations: 1,000,000
Message Size: 256 bytes
Avg Time: 1,680 nanos
Min Time: 1379 nanos
Max Time: 7020 nanos
75%: avg=1618 max=1782 nanos
90%: avg=1653 max=1869 nanos
99%: avg=1675 max=1964 nanos
99.9%: avg=1678 max=2166 nanos
99.99%: avg=1679 max=5094 nanos
99.999%: avg=1680 max=5638 nanos

在我的文章短于2微秒的套接字通信中,我将更多地讨论Java和反应堆模式。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12099446

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档