dcmtk 3.6 網絡性能優化

背景

在項目中使用dcmtk 3.6.2之後版本開發SCP(windows系統),使用中發現性能很差。DCMTK自己編譯提供的storescp程序,如果不加任何參數,一樣有問題。經過調研,找到解決方案。

  • 主要現象
    1. scu建立accociation的請求發出後,大約要等待10s左右,才能開始發送第一張圖。
    2. 在某些windows 10機器上,即使在局域網內,1s中接收非壓縮CT圖像的速度大約只有4張。狀態好一點的機器,大約11張左右。本機scu發給同一臺機器的scp速出超過20張。

問題1 - 建立association慢解決方案

出現問題1是由於默認情況,dcmtk收到accosication請求之後,會試圖把IP轉成hostname。在局域網沒有DNS支持的情況下,會耗費很多時間。

對於預編譯的storescp.exe 可以通過-disable-host-lookup" (short: -dhl) 禁用這步操作。

對於開發者,可以在程序開始的時候,設置全局變量 dcmDisableGethostbyaddr.set(OFTrue); 禁用這個操作改善速度。

dcmtk開發這對此的說明見
https://forum.dcmtk.org/viewtopic.php?f=4&t=25

The problem is most likely related to reverse DNS lookup. When accepting an association, DCMTK attempts to find out the remote system’s hostname. This can take some time if the remote system is not known to the local DNS, in particular on Windows systems. Try to start the application with the additional command line option “–disable-host-lookup” (short: -dhl) which was introduced with DCMTK 3.5.0.

問題2 - 小文件傳輸慢解決方案

通過添加log和用網絡工具抓包,發現性能的主要瓶頸是:在scp接收完一張圖之後,向SCU發送response花了大約200ms。從代碼看,一個圖接收完,立刻就調用了resoponse發送。但是,從IP數據包看,這個response實際上在大約200ms後才真正發給scu。

經過深入調研,發現和TCP網絡的Nagle algorithm有關。這個算法試圖把一些小的數據包堆在一起發送。所以,對於response這種小數據包,就會阻塞一直到這個算法設置的超時(windows下是200ms)。微軟對於這個問題的解釋可以參考 https://support.microsoft.com/en-us/help/214397/design-issues-sending-small-data-segments-over-tcp-with-winsock

DCMTK對此提供兩個解決方法, 見https://forum.dcmtk.org/viewtopic.php?f=4&t=4632

Starting with DCMTK 3.6.2, the Nagle algorithm is not disabled by default since this does not seem to be appropriate (anymore) for most modern operating systems. In order to change this default, the environment variable TCP_NODELAY can be set to “1” (see envvars.txt for details). Alternatively, the macro DISABLE_NAGLE_ALGORITHM can be defined to change this setting at compilation time (see macros.txt for details).

翻譯過來就是:

開發者覺得在現在操作系統中禁用Nagle algorithm不合適。所以,從DCMTK 3.6.2,不再默認禁用Nagle algorithm。如果希望繼續禁用Nagle algorithm,可以在環境變量彙總把TCP_NODELAY設置成"1" (envvars.txt中有詳細說明)。或者,通過定義DISABLE_NAGLE_ALGORITHM宏,在編譯的時候禁用(macros.txt中有詳細說明)。

簡單說,如果程序已經編譯好了無法更改,可以設置環境變量TCP_NODELAY=1。這個設置影響操作系統中所有網絡程序。更好的方式是重新編譯DCMTK,增加預編譯宏DISABLE_NAGLE_ALGORITHM

Windows下如果希望通過cmake直接指定這個宏,同時dcmtk編譯成靜態庫,需要把DCMTK_OVERWRITE_WIN32_COMPILER_FLAGS設成OFF,否則,CMAKE_CXX_FLAGS會被設置成固定值。參考CMake/dcmtkPrepare.cmake

經過測試,局域網內這個修改可以把CT image的接收速度提高到20張/s以上。

有興趣,可以研究這個文件裏面的相關代碼dcmnet/libsrc/dul.cc

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章