s2.
@sakura26eq
Sat, Mar 7, 2020 2:57 PM
2
[請教][程式] 如果要寫一隻可以穩定控制輸出速度,且輸出間隔小於一微秒的程式,怎麼做比較好?
例如我希望每秒打10000個封包出去,一般sleep最小單位就是一微秒,但如果sleep(1)然後loop 10是不work的,因為每次發送似乎都有啟動最短時間,例如4ms,且會因為loop的長度有所改變。
中等質量工程黑喵
@goot1214
Sat, Mar 7, 2020 4:21 PM
雖然不是解答 不過有商用軟體可以設定精準時間間格
中等質量工程黑喵
@goot1214
Sat, Mar 7, 2020 4:21 PM
Windows 即時運動控制 | RTOS – 即時作業系統
中等質量工程黑喵
@goot1214
Sat, Mar 7, 2020 4:22 PM
根據說明可以有1mirco second 的 timer
中等質量工程黑喵
@goot1214
Sat, Mar 7, 2020 4:22 PM
開源的有
FreeRTOS - Market leading RTOS (Real Time Operating ...
中等質量工程黑喵
@goot1214
Sat, Mar 7, 2020 4:24 PM
不過開源的freertos我不確定有沒有到1微秒的timer
中等質量工程黑喵
@goot1214
Sat, Mar 7, 2020 4:25 PM
OpenRTOS - FreeRTOS
中等質量工程黑喵
@goot1214
Sat, Mar 7, 2020 4:27 PM
不過要如何”自己“寫出一個在極小時間間格的timer我就不清楚了
中等質量工程黑喵
@goot1214
Sat, Mar 7, 2020 4:27 PM
另外這個timer執行的工作必須在時間間隔內完成
中等質量工程黑喵
@goot1214
Sat, Mar 7, 2020 4:29 PM
例如一微秒的timer設定的工作必須在一微秒內處理完 避免第二次觸發時間被延遲
中等質量工程黑喵
@goot1214
Sat, Mar 7, 2020 4:30 PM
希望對你有幫助,另外個人使用經驗是時間間隔是1毫秒
中等質量工程黑喵
@goot1214
Sat, Mar 7, 2020 4:33 PM
已經若是要透過網路線輸出這個timer訊號 1微秒會可能會太快 要看用的網路卡是否能支援到微秒等級的速度
s2.
@sakura26eq
Sat, Mar 7, 2020 4:37 PM
我發現我打錯...是小於毫秒,比微秒大XDD
實際的使用情境是每秒打十萬數據之類
s2.
@sakura26eq
Sat, Mar 7, 2020 4:38 PM
目前都是先用loopback介面打,所以應該還扛得住,網路卡之後再想辦法
s2.
@sakura26eq
Sat, Mar 7, 2020 4:39 PM
RTOS我相信可以做到,不過目前還是想先找一般Linux架構下的解法,畢竟真要搞他本身就可以發展一套產品出去了
s2.
@sakura26eq
Sat, Mar 7, 2020 4:40 PM
中等質量工程黑喵
: 感謝分享,我也是寫到一半才發現這個有夠難抓,低於ms的時候函數呼叫之間的切換延遲在之前是從沒想過的問題
中等質量工程黑喵
@goot1214
Sat, Mar 7, 2020 4:43 PM
每秒打10000個封包 相當於100微秒一個封包 比微秒大很多XD
s2.
@sakura26eq
Sat, Mar 7, 2020 4:49 PM
對啊,差1000倍ORz
中等質量工程黑喵
@goot1214
Sat, Mar 7, 2020 4:53 PM
若是執行工作又很複雜。個人經驗是在timer內放狀態機管理 ,把工作分成幾個狀態處理 ,確保每次的執行時間函式都在timer間格內。
中等質量工程黑喵
@goot1214
Sat, Mar 7, 2020 4:55 PM
不過若是只是printf(?) timer內部應該不會需要太複雜的架構,函式內越簡單越好
中等質量工程黑喵
@goot1214
Sat, Mar 7, 2020 4:56 PM
另外內部不要動態宣告變數 執行時間也會比較穩定
中等質量工程黑喵
@goot1214
Sat, Mar 7, 2020 4:59 PM
最好是用指標跟固定記憶體位置讀取跟寫入
中等質量工程黑喵
@goot1214
Sat, Mar 7, 2020 5:02 PM
因為這樣作業系統就不用花效能去管理記憶體。 若是在timer內部動態宣告變數,理論上分配的記憶體位置會每次不同?這會導致執行時間不固定 (微秒等級的。
s2.
@sakura26eq
Sat, Mar 7, 2020 5:03 PM
是這樣沒錯啦,甚至最好直接用C或組語可以完全控制記憶體與變數...雖然知道怎麼做但是有點蛋疼啊XDDD
s2.
@sakura26eq
Sat, Mar 7, 2020 5:07 PM
我先把它改成timer 架構好了,目前的程式是java對底層控制力有限
中等質量工程黑喵
@goot1214
Sat, Mar 7, 2020 5:12 PM
對java不熟 個人描述的經驗都是建立在c/c++上
中等質量工程黑喵
@goot1214
Sat, Mar 7, 2020 5:23 PM
還有一個簡單測試可以做 timer設定1ms,只做 i++ 設定終止條件是i==60000。看看執行完畢時 現實的時間是否是剛好過了一分鐘 還是遠超過一分鐘
中等質量工程黑喵
@goot1214
Sat, Mar 7, 2020 5:25 PM
如果簡單測試結果就過不了
那還是換個綁底層的realtime os
s2.
@sakura26eq
Sun, Mar 8, 2020 3:53 AM
有點難纏的是,一定會超過,因為幾乎都是在虛擬化環境中跑(死目
s2.
@sakura26eq
Sun, Mar 8, 2020 3:54 AM
也因為是虛擬化環境,RTOS可能沒辦法發揮真實效果...
中等質量工程黑喵
@goot1214
Sun, Mar 8, 2020 4:21 AM
虛擬化就真的不行了 rtos是直接控制到cpu指令集的程度 很吃硬體狀態 。若是硬體不支援 timer就會不準, 所以cpu跟網路卡(若是要連外)一定要可以支援
中等質量工程黑喵
@goot1214
Sun, Mar 8, 2020 4:21 AM
網路卡可以參考這個清單
中等質量工程黑喵
@goot1214
Sun, Mar 8, 2020 4:21 AM
https://www.intervalzero.com/...
中等質量工程黑喵
@goot1214
Sun, Mar 8, 2020 4:23 AM
雖然rtx64系列都是以 windows+intel為主 linux系列可能要查freertos支援的情況
中等質量工程黑喵
@goot1214
Sun, Mar 8, 2020 4:25 AM
然後如果使用rtos timer不要用sleep控制 要用 interrupt控制
中等質量工程黑喵
@goot1214
Sun, Mar 8, 2020 4:26 AM
用sleep 函式結束的時間會影響到下次開始執行的時間
中等質量工程黑喵
@goot1214
Sun, Mar 8, 2020 4:31 AM
不過這個清單的網路卡也不是直接支援
中等質量工程黑喵
@goot1214
Sun, Mar 8, 2020 4:32 AM
rtx64會根據網路卡再裝一個 rtx版本的驅動
中等質量工程黑喵
@goot1214
Sun, Mar 8, 2020 4:32 AM
不曉的是否會導致失去與網際網路連線功能
中等質量工程黑喵
@goot1214
Sun, Mar 8, 2020 4:33 AM
因為rtx64是用一種叫ethercat的協定 透過網路線連線到工業設備(伺服馬達之類的)
中等質量工程黑喵
@goot1214
Sun, Mar 8, 2020 4:35 AM
普通的乙太網路不曉得在rtx的驅動下是否能運作 (個人是透過wifi晶片連外 因為對外聯網無realtime的需求
s2.
@sakura26eq
Sun, Mar 8, 2020 4:44 AM
剛剛有人提到直接搭上CPU時脈用組語去控制打封包來調整速度XDDD
我百年沒用組語了
中等質量工程黑喵
@goot1214
Sun, Mar 8, 2020 5:49 AM
把pc當成embedded在用XD
中等質量工程黑喵
@goot1214
Sun, Mar 8, 2020 5:57 AM
Linux 核心設計: Timer 及其管理機制 - HackMD
中等質量工程黑喵
@goot1214
Sun, Mar 8, 2020 5:57 AM
linux有核心變數管理CPU時脈 跟記錄過了多少count
中等質量工程黑喵
@goot1214
Sun, Mar 8, 2020 5:58 AM
不過個人比較喜歡用現成的所以完全沒深入這方面的底層過
JokerCatz
@jokercatz
Sun, Mar 8, 2020 7:00 AM
golang 的 sleep 有到 nano sec 呦
JokerCatz
@jokercatz
Sun, Mar 8, 2020 7:02 AM
Sun, Mar 8, 2020 7:03 AM
其實你要超精準的乾脆 while true 去 check timestamp 算了? and 不是 check 時間後打一次,而是到該時間缺了幾次的方式去 loop 應該能節省 check 量才是
s2.
@sakura26eq
Sun, Mar 8, 2020 7:09 AM
JokerCatz
: 之所以在找sleep是因為,被測試的程式也在同一台機器上且cpu senstive,吃光cpu去送會有點緊張。
且如果打的數據量peak太高可能會導致掉包,希望讓送出頻率比較和緩一點,不然現有工具事實上就可以打準確數量了
s2.
@sakura26eq
Sun, Mar 8, 2020 7:12 AM
Thread (Java Platform SE 7 )
突然發現原來原生有支援,但不知道為什麼無法啟用,怪怪的
s2.
@sakura26eq
Sun, Mar 8, 2020 7:14 AM
看來還是沒辦法sleep低於1ms, 會1ms起跳
JokerCatz
@jokercatz
Sun, Mar 8, 2020 10:41 AM
你可以用 Pi 系列大絕招啊,保留其中一個 core 給他用(笑翻)Linux 底層支援哩
isolcpus << 用這指令限制 Linux 能使用的 CPU 數量,你會看到保留的 CPU 永遠不會使用,然後把該 process 配給該 CPU 即可
JokerCatz
@jokercatz
Sun, Mar 8, 2020 10:42 AM
Sun, Mar 8, 2020 10:45 AM
Pi 系列硬體低延遲大概都會建議你這樣搞,或是會燃燒 CPU 的那種特例 process,大概就切割成專用 CPU 哩 X"DD(之前在玩 HUB75 玩到的鬼 ... 哈哈)
s2.
@sakura26eq
Sun, Mar 8, 2020 11:54 AM
對啊,有考慮這樣做過,不過這個支線岔有點遠,等手上高優先的東西搞完才有空去弄...
s2.
@sakura26eq
Sun, Mar 8, 2020 3:41 PM
找到一個LockSupport.parkNanos(1),也是有問題,給什麼參數結果都一樣...
s2.
@sakura26eq
Sun, Mar 8, 2020 3:41 PM
暫時使用統計數學去在runtime做參數自我修正,先結案
載入新的回覆
例如我希望每秒打10000個封包出去,一般sleep最小單位就是一微秒,但如果sleep(1)然後loop 10是不work的,因為每次發送似乎都有啟動最短時間,例如4ms,且會因為loop的長度有所改變。
實際的使用情境是每秒打十萬數據之類
那還是換個綁底層的realtime os我百年沒用組語了
不過個人比較喜歡用現成的所以完全沒深入這方面的底層過且如果打的數據量peak太高可能會導致掉包,希望讓送出頻率比較和緩一點,不然現有工具事實上就可以打準確數量了
突然發現原來原生有支援,但不知道為什麼無法啟用,怪怪的
isolcpus << 用這指令限制 Linux 能使用的 CPU 數量,你會看到保留的 CPU 永遠不會使用,然後把該 process 配給該 CPU 即可