[問題] 如何暫停microsecond等級的時間?

看板C_and_CPP (C/C++)作者 (T-PANY FOREVER)時間11年前 (2015/02/15 16:43), 編輯推噓4(4031)
留言35則, 6人參與, 最新討論串1/1
各位版友好,有些關於時間方面的問題想請教大家一下 最近在用c++寫簡單的socket程式,內容為Client端每隔幾秒要傳資料給Server端這樣 因為要做研究的關係,我想知道Client每隔1秒或是每隔1.000010秒傳資料給Server 對於我們想知道的結果會有什麼影響, 但是這就是會遇到問題了 就我這幾天網上查的結果, 似乎沒有任何一個function可以達到microsecond等級的暫停 即使我用usleep(1000010)也沒辦法精確的暫停1.000010秒 畢竟系統呼叫usleep()這個function似乎就要1ms到2ms的時間了(?) 對於usleep()我是這樣計算時間的: #include <iostream> #include <sys/time.h> using namespace std; int main(){ timeval t1, t2; double elapsedTime; gettimeofday(&t1, NULL); usleep(1000010); //睡1.000010秒 gettimeofday(&t2, NULL); elapsedTime = (t2.tv_sec - t1.tv_sec); elapsedTime += (t2.tv_usec - t1.tv_usec) / 1000000.0; cout << elapsedTime << " seconds.\n"; return 0; } 嘗試多次的結果, elapsedTime還是會比預期多1ms到2ms 不知道這跟系統的timer resolution有沒有關係? 我在MAC OSX上用以下的code所測到timer resolution為3~5 microsecond左右 #include <iostream> #include <ctime> #include <unistd.h> using namespace std; int main() { clock_t t1, t2; t1 = t2 = clock(); // loop until t2 gets a different value while(t1 == t2){ t2 = clock(); } // print resolution of clock() cout << (double)(t2 - t1) / CLOCKS_PER_SEC * 1000000.0 << " us.\n"; return 0; } 對於暫停microsecond等級的時間版友有任何想法可以提點一下嗎? 先謝謝各位! -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 203.73.50.125 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1423989836.A.3D3.html

02/15 16:47, , 1F
一般來說會用 select() 來做,經驗上來說比較精確些
02/15 16:47, 1F

02/15 17:28, , 2F
timer 這種東西, 很難準的, 和跑的 OS & H/W 有關.
02/15 17:28, 2F

02/15 17:30, , 3F
我曾跑過 FreeRTOS ...等一些嵌入式系統, 也沒法保證準確.
02/15 17:30, 3F

02/15 17:31, , 4F
只能"盡量"去做. 基本想法是針對你要實驗的那段 code
02/15 17:31, 4F

02/15 17:31, , 5F
提高它的 process or thread priority, 然後其他的,
02/15 17:31, 5F

02/15 17:32, , 6F
一些 service..有的沒的, 能關就盡量關.
02/15 17:32, 6F

02/15 17:32, , 7F
或是直接跑嵌入式, 上面只跑你那支程式 XDDD
02/15 17:32, 7F

02/15 17:34, , 8F
另外一個做法就是在相同環境, 做大量實驗.
02/15 17:34, 8F

02/15 17:35, , 9F
舉例: 你要 sleep 1ms, 但實際你是下 0.9ms, 其中 0.1ms
02/15 17:35, 9F

02/15 17:35, , 10F
是之前實驗告訴你的系統 overhead
02/15 17:35, 10F

02/15 17:36, , 11F
XDDD
02/15 17:36, 11F

02/15 19:47, , 12F
lf大所言甚是XD 這方法我有try過,不過準確度很難捉摸XD
02/15 19:47, 12F

02/15 19:48, , 13F
Lilo大說的select function我也會去研究看看, 謝謝兩位!
02/15 19:48, 13F

02/16 00:58, , 14F
while loop然後拿rdtsc的結果出來比,檢查是否過了1ms
02/16 00:58, 14F

02/19 16:33, , 15F
沒發現d大的留言!!... 感謝!
02/19 16:33, 15F

02/19 22:36, , 16F
rdtsc 是個爭議…
02/19 22:36, 16F

02/20 15:51, , 17F
E大,想問一下rdtsc在多核心上是不是會有問題呢??
02/20 15:51, 17F

02/20 17:39, , 18F
select(time_fd)已經是user space能用的最準確的了
02/20 17:39, 18F

02/20 17:39, , 19F
其他的不是平台限定 就是有移植問題
02/20 17:39, 19F

02/20 17:40, , 20F
rdtsc算是平台實作不同的作法就是
02/20 17:40, 20F

02/20 17:40, , 21F
另外基本上這個應該只有Intel/AMD有 其他都CPU都沒有
02/20 17:40, 21F

02/20 20:21, , 22F
rdtsc 在多核上會有問題外 , 同時讓人意外的和電源管理有
02/20 20:21, 22F

02/20 20:23, , 23F
關.總結三個理由不用 rdtsc(這三個理由到各大論壇都可得)
02/20 20:23, 23F

02/20 20:23, , 24F
1. 不能保證每個 cores 的 TSC (Time Stamp Counter)同步
02/20 20:23, 24F

02/20 20:24, , 25F
2. 省電模式時(ex:NB) , CPU 時脈率會隨之變化,不是常數
02/20 20:24, 25F

02/20 20:26, , 26F
3. 亂序執行時取得的週期數不準
02/20 20:26, 26F

02/20 20:26, , 27F
Linux 下取代的方案我不熟,這個我就不贅述了。
02/20 20:26, 27F

02/20 20:33, , 28F
講到 rdtsc 好像有些離題了...
02/20 20:33, 28F

02/20 20:54, , 29F
謝謝E大詳細解說,我也在四處看有沒有可用的函數, 不過
02/20 20:54, 29F

02/20 20:55, , 30F
這問題看來是受限於系統本身的限制, 暫時是無解了.. 我
02/20 20:55, 30F

02/20 20:57, , 31F
先改成用K大也提到select試試看有沒有辦法改善一點..
02/20 20:57, 31F

02/20 20:57, , 32F
^的
02/20 20:57, 32F

02/21 00:03, , 33F
select在新版linux kernel有幫你包好 叫做timefd
02/21 00:03, 33F

02/21 00:03, , 34F
直接用timefd可以省掉你非常多的麻煩
02/21 00:03, 34F

02/21 00:04, , 35F
不過普遍來講 select算是跨平台可兼容就是
02/21 00:04, 35F
文章代碼(AID): #1Ku5nCFJ (C_and_CPP)
文章代碼(AID): #1Ku5nCFJ (C_and_CPP)