C_and_CPP 板


LINE

如我前面說的, 這個問題要看 CPU 和作業系統而定... CPU 的 rdtsc (rdtscp) 指令讀出來的 counter 直接影響計時精確度, Windows 作業系統和 UNIX 家族各自有各自的 function call ... 需要使用到精確時鐘的操作大致有以下幾種: 1. 時鐘, 看目前時間, 或計算兩次看錶之間經過多久 2. 等待, delay 一段時間不做事 3. 鬧鐘, 某個時間要醒來做某事 ○UNIX: 最準的當然是 POSIX.1-2001 規定的 clock_* 和 timer_* 系列: clock_gettime(): 取得目前時間 clock_getres(): 取得精確度 clock_nanosleep() 或 nanosleep(): delay, 保證睡過頭 timer_create(), timer_settime() 系列: 鬧鐘 以上計時單位都是 ns, 使用 Sandy Bridge 以後的 CPU , clock_getres() 回傳的 精確度就一律是 1 ns 了,在那之前的 CPU 到底哪些準哪些不準我沒有仔細研究... 不夠準的: select(): 可以代替 sleep(), 在古代沒有 nanosleep() 而 usleep() 又很兩光地 busy waiting 時, select() 曾經是精準 sleep 的最佳解。 usleep(): 已過氣, 建議改用 nanosleep() ualarm(): 可以用 us 為單位指定時間發 SIGALRM gettimeofday(): 取得目前時間 以上計時單位是 us, 而且你無法取得精確度... 但可以慶幸的是 Linux 本來精確度 就是看 CPU, 所以普通的 PC 精確度 < 1 us 是基本的... clock(): 老掉牙 function, 單位是 clock, 用 CLOCKS_PER_SEC 可以換算成秒, 我的 Linux 上 CLOCKS_PER_SEC 是 1000000 也就是說 clock = us 但印象中以前看過 #define CLOCKS_PER_SEC 1000 的舊開發環境... time(): 最常見的時間函式, 回傳單位是秒... 我每次看見有人寫 srand(time(NULL)); 就會抓狂... 現在科學昌明的 21 世紀有 /dev/urandom 這個東西耶... alarm(): 令人懷念的鬧鐘, 以秒計費, 不, 以秒計時, SIGALRM 給大家製造不少麻煩 比如說中斷本來應該 block 住的 system call, 讓它產生 EAGAIN 錯誤... ○Windows: 最準的是 High-Resolution Timer 系列, 其精確度和 CPU 的 rdtsc 一樣準: QueryPerformanceCounter(): 取得 rdtsc 的 counter 值 QueryPerformanceFrequency(): 取得一秒有幾個 counter, Sandy bridge 以後的 CPU, 其 frequency 值等於 CPU 時脈 (2.66 GHz CPU, freq = 2672760000) 這個 counter 精確度 < 1 ns 但很遺憾地, Windows 沒有對應的 ns 級 sleep 和 alarm function, 甚至連 us 級都從缺... 不夠準的: Multimedia Timer: 以前曾經是最準的 timer, 但這個準確度是有代價的, 當你用 timeBeginPerios(1) 設定精確度為 1 ms 的時候, 原本 18.2Hz 的 timer chip 會被加速, 導致 timer interrupt 數量暴增, 然後整個系統效能反而變得很悲劇... GetTickCount(): 單位是 ms, 但實際精確度無法得知, 通常就是同上... 另外它每 49.7 天會 overflow 一次, 這曾經造成 Win98 著名的 49.7 天 當機 bug 以及 Debug 模式的 GetTickCount overflow condition test GetTickCount64(): 這下再也不會 overflow 了... (鬆一口氣) clock(): 作用和 Linux 的 clock() 一樣, 只不過 CLOCKS_PER_SEC 是 1000 GetSystemTime(), GetSystemTimeAsFileTime(): 最小單位是 ms 很兩光的是你沒辦法直接取得 64-bit LARGE_INTEGER 的時間值... Sleep() 和 SleepEx(): 單位是 ms, 但實際精確度同 Multimedia Timer SetTimer(): 最常見的鬧鐘, 最小值 10 ms 起跳。 順帶一提 rdtsc 指令並不是絕對神準, 有幾個狀況會出槌, 但這裡並不是組合語言板, 為了避免被水桶還是就此打住。 --



※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 220.137.5.19
1F:推 UncleHS:linux下有perf可以用呀 09/25 02:18
2F:→ Schottky:perf 用途不同吧... 09/25 02:24
3F:推 Bencrie:推整理 XD 09/25 09:29
4F:→ Bencrie:usleep 會 busy waiting ? 不是應該把 CPU 讓出去嗎 09/25 09:30
感謝指正, 古代許多 UNIX 的 libc 確實是用 busy waiting 在實作, 我記得在 W. Richard Stevens 的 UNIX Network Programming 有提到。由於 usleep 是個 library function, 不是 system call, 所以要看各家 C library 不同實作方式。 剛剛看了 GNU libc 2.18 的 source code, 在有 nanosleep() system call 的 Linux 上是用 nanosleep 實作, 在沒有 nanosleep() 的古代 BSD 上是用 select() 實作, 所以使用 glibc2 的系統應該是不會有 busy waiting 問題。 Linux 的 nanosleep() 是 kernel 裡的 system call, 以前曾經發生過在某個 mode 之下為了種種原因還是用 busy waiting 來實作, 不過 2.6 和 3.x 之後的 kernel 已經修正, 不用再擔心了。
5F:推 CaptainH: 09/25 09:40
6F:→ purincess:有DVFS的CPU用rtdsc會爆炸的..XD 09/25 12:26
DVFS (CPU 變頻) 這功能被罵翻了 XD ※ 編輯: Schottky 來自: 220.137.37.104 (09/25 13:03)
7F:推 Bencrie:喔喔 感謝說明 XD 09/25 13:09
8F:推 user1120:推! 09/25 14:47
9F:→ licheer:Sleep()不準 09/25 15:12
10F:→ Schottky:Sleep()是不準,不過Windows平台有其他sleep可選擇嗎? 09/25 19:15
11F:→ Schottky:也只能睡飽了再用QueryPerformanceCounter()估計誤差了 09/25 19:29
12F:推 lc85301:可是用/dev/urandom起始srand比較麻煩OAO 09/25 22:44
13F:→ lc85301:還是直接用urandom取代srand 09/25 22:45
14F:→ Schottky:不在乎極速不夠高的話 urandom 就直接用了(有些人會在意) 09/25 23:01
15F:→ Schottky:rand()和srand()也是個歷史遺毒--取亂數幹嘛還要播種 09/25 23:02
16F:→ Schottky:像PHP那樣第一次用rand()時自動seed不就很方便嗎? 09/25 23:03
17F:→ Schottky:urandom的演算法用SHA,比大部份C lib的rand用LFSR好多了 09/25 23:04
18F:→ Schottky:LFSR只是統計上的特性合標準,不可預測性是很爛的 09/25 23:22
19F:→ tomnelson:唉~ 以前曾經遇過49.7天的bug作祟 09/25 23:34
21F:推 realmeat:詳細推 09/26 19:34
22F:→ licheer:可以掛RTOS來用 09/26 20:01
23F:推 james732: 推詳細 05/21 17:45
24F:推 os653: 取亂數需要播種這玩意兒在寫replay的時候還是很有用的 05/22 18:44







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:e-shopping站內搜尋

TOP