奧義: 讀取最佳化
事先說明:本文提到的演算法,並未在本人服務過的公司使用過,相關的演算法實作也未參與,本文純粹是最近 1 年思索研究的心得總結。什麼是讀取最佳化?一樣拿台達 DOPSoft 當範例,通訊參數設定如下:
上圖左下角有個「讀取最佳化」,它是指什麼呢?我們在畫面上擺 3 個數值顯示元件實驗看看:
再執行 Modbus RTU Slave 模擬軟體,觀察通訊行為:
從上圖可以看到 W40010, W40011, W40016 被合併成一個 command 送給 Modbus RTU Slave 模擬器:
這樣做有什麼好處?我們來看 Modbus Read Holding Registers protocol:
從上圖可以看到,讀取 1 word 的通訊成本是 19 bytes,19 bytes 除了上面提到的資訊外,包含 2 bytes CRC,Request/Response 的 3.5bytes delay(算 4bytes)。
如果 W40010, W40011, W40016 分 3 次讀取,就需要花費 19 + 4 + 19 + 4 + 19 = 65bytes,以 9600 none parity, 8 data bits, 1 stop bits 為例,則通訊時間
1/9600*10*65 = 68ms
而合併後只需要 32ms (1/9600*10*(27+4)),足足快了 50%!! 更不用說如果要讀取的位址一多會差到幾倍了!
總結讀取最佳化的目的:
- 減少 round trip time(往返時間)
- 盡可能一次讀取多筆資料,改善系統反應
本人的讀取最佳化演算法是一個 two pass 演算法:
Pass1
Pass1 很明顯可以看出來是合併鄰接位址,這部份在另外兩篇已經提過,相對 Pass2 還算簡單。Pass2
Pass2 難點有兩個。第一,未使用區域上限為何?未使用區域的讀取成本 + 下一個位址的讀取成本,不能超過單獨讀取一個位址的讀取成本(成本應包含末尾的 checksum、CRC,當然也不能超過 protocol spec),用圖形表示如下:
筆者試算了一下,大概可以理解台達為何如此設計,假設欲讀取 Holding Register 位址如下
- W40010
- W40011
- W40019
分兩次讀取花費時間:42ms
只得到 7% 的增益,但如果以 8 bytes 計算, W40019 換成 W40016,一次讀取花費時間為 32ms,得到 24% 的增益。以筆者的經驗,小於 10% 的改善很難有什麼感覺,這大概是為何台達取 8 bytes 的原因,8 bytes 剛好也是 14/2 最接近的值。
第二點就頭大了,如果你有一堆已經通過 Pass1 合併的位址:
如果這些未使用區域都沒有超過第一點的上限,但因為 protocol spec 的限制,是不可能一次全部讀回的,以 Modbus Holding Register 為例,位址範圍 64K words,protocol spec 限制一次最多只能讀回 125 words,所以問題是你要如何以 125 words 為上限對這些位址進行分組?
也許有人還不知道這個問題有多難,下面是一個簡化的例子,以 5 為區塊大小,3 個區塊就可以產生很多組合:
大家都知道排列組合的結果是階乘(factorial),要透過所有的排列組合找出最佳解,在空間與時間上會耗費巨大成本,更別提在嵌入式系統上幾乎不可行。這種涉及所有組合的問題常常是 NP complete。
拋開完美主義的心態,其實這時候只要能找出近似解就可以了(如同前面台達對未使用區域範圍的處理),使用貪心演算法(Greedy Method)就可以簡單處理這個問題:
- 找出最大的使用區塊
- 由這個最大區塊找出左邊/右邊最大能合併的位址
- 重複 1 直到處理完所有區塊
其他要注意的地方
TCP/IP based protocol
如果用 TCP/IP 通訊,就不用太在意未使用區域,以 Ethernet 來說 MTU(最大傳輸單元)是 1500bytes,即使未使用區域很大一塊也不用太在意,即使超出 MTU,以 Ethernet 至少 10Mbps - 100Mbps 的頻寬也沒什麼影響。
不可分割的一部分
有些區塊不能被分成兩次讀取,例如以 2 個 Holding Register 代表一個 IEEE754 32bits 浮點數,在優化時就不能加以切割。
尾聲
不只是 HMI,Modbus Gateway(還有一堆其他 xxx Gateway)也可以使用本文的演算法在 run-time 時優化通訊,某些廠牌還起了個什麼 Agent mode、intellegnt optimization 之類高大上的廣告詞,今天就來個大揭秘。
為何要寫下這一系列呢?
1993 年寫出毀滅戰士(DOOM)的首席工程師 John Carmack,在 1997 年就釋出 source code。當然筆者的成就與遠遠無法與 John Carmack 相比(他光靠 DOOM 就賺到法拉利還多到可以送人,筆者只有機車一台),但 John Carmack 認為 1993 年他開發出的技術遲早會有人學會跟上。
相比之下,筆者這點三腳貓功夫也沒什麼好弊帚自珍,還不如寫出來公諸於世,放下過去...
沒有留言:
張貼留言