![](/img/trans.png)
[英]Is is possible to use NIO Selector for FileChannels in Java and/or Android?
[英]Java NIO selector minimum possible latency
我在Linux over loopback(127.0.0.1)上使用優化的Java NIO選擇器進行一些基准測試。
我的測試非常簡單:
對於往返時間,我得到以下結果:
但這里的問題是我正在傳輸100萬條消息。
如果我只旋轉10條消息,我會得到非常不同的結果:
如果我錯了,請糾正我,但我懷疑,一旦我們讓NIO選擇器旋轉,響應時間就變得最佳。 但是,如果我們發送的消息之間有足夠大的間隔,我們會支付喚醒選擇器的價格。
如果我只發送一條消息,我會得到150到250微秒的不同時間。
所以我對社區的問題是:
1 - 我的最小時間為13微秒,平均為19微秒,這次往返包測試。 看起來我到目前為止擊敗了ZeroMQ所以我可能會在這里遺漏一些東西。 從這個基准測試來看,ZeroMQ在標准內核上的平均時間為49微秒(99%)=> http://www.zeromq.org/results:rt-tests-v031
2 - 當我旋轉一條或幾條短信時,我能做些什么來改善選擇器的反應時間嗎? 150微米看起來不太好。 或者我應該假設在prod環境中選擇器不會完全?
通過忙於圍繞selectNow()旋轉,我能夠獲得更好的結果。 發送少量數據包仍然比發送許多數據包更糟糕,但我認為我現在正在達到選擇器性能限制。 我的結果:
結論
因此,看起來UDP數據包往返的物理屏障平均為10微秒,盡管我得到了一些數據包,以8微秒(最短時間)進行旅行。
隨着忙碌的旋轉(感謝彼得),我能夠從平均200微秒變為單個數據包的平均65微秒。
不確定為什么ZeroMQ 慢5倍 。 ( 編輯:也許是因為我通過環回在同一台機器上測試它,而ZeroMQ使用兩台不同的機器?)
你經常看到那些喚醒線程的情況可能非常昂貴,不僅僅是因為線程需要花費時間才能喚醒,但是線程運行速度慢了2-5倍,之后幾十微秒就像緩存一樣
我過去避免這種情況的方式就是忙等待。 不幸的是,selectNow每次調用它時都會創建一個新集合,即使它是一個空集合。 這會產生如此多的垃圾,不值得使用。
解決這個問題的一種方法是忙於等待非阻塞套接字。 這不會特別好地擴展,但可以為您提供最低的延遲,因為線程不需要喚醒,並且在此之后運行的代碼更可能在緩存中。 如果你也使用線程親和力,它可以減少你的線程干擾。
我還建議嘗試減少代碼鎖定和減少垃圾。 如果這樣做,您可以使用Java進程,該進程在90%的時間內在100微秒內發送對傳入數據包的響應。 這將允許您在到達時以100 Mb處理每個數據包(由於帶寬限制,最多相隔145微秒)對於1 Gb連接,您可以非常接近。
如果你想在Java中的同一個盒子上進行快速進程間通信,你可以考慮像https://github.com/peter-lawrey/Java-Chronicle這樣使用共享內存來傳遞具有往返延遲的消息(這很難做到)有效地使用小於200 納秒的插座。 它還可以保留數據,如果您只想快速生成日志文件,則它非常有用。
如果正確調整選擇器,可以在不到2微秒的時間內通過Java進行插槽間通信。 以下是我對256字節UDP數據包的單向結果:
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.