usleepに続いてnanosleepの精度を確認。
gettimeofdayはマイクロ秒単位までしか測定できませんが、ナノ秒単位の精度がでることはなさそうなので気にしません。
検証プログラム
#include <stdio.h> #include <sys/time.h> double get_time_sec(){ struct timeval tv; gettimeofday(&tv, NULL); return tv.tv_sec + (double)tv.tv_usec*1e-6; } int main(){ long ns; puts(" 指定 停止 誤差"); for(ns=1;ns<(long)10e8;ns*=10){ double start,end; struct timespec tc; tc.tv_sec = 0; /* sec */ tc.tv_nsec = ns; /* nano sec */ start = get_time_sec(); nanosleep(&tc, NULL); end = get_time_sec(); printf("%.9f : %.9f : %.9f sec\n", ns/1.0e9, end - start, end - start - ns/1.0e9); } return 0; }
実行結果
Linux
[mikeda@cent c]$ ./nanosleep_check 指定 停止 誤差 0.000000001 : 0.000766993 : 0.000766992 sec 0.000000010 : 0.000874043 : 0.000874033 sec 0.000000100 : 0.000933886 : 0.000933786 sec 0.000001000 : 0.000940084 : 0.000939084 sec 0.000010000 : 0.000939131 : 0.000929131 sec 0.000100000 : 0.000941038 : 0.000841038 sec 0.001000000 : 0.001937866 : 0.000937866 sec 0.010000000 : 0.010936975 : 0.000936975 sec 0.100000000 : 0.100923061 : 0.000923061 sec [mikeda@cent c]$ ./nanosleep_check 指定 停止 誤差 0.000000001 : 0.002135038 : 0.002135037 sec 0.000000010 : 0.001869202 : 0.001869192 sec 0.000000100 : 0.001936913 : 0.001936813 sec 0.000001000 : 0.001938105 : 0.001937105 sec 0.000010000 : 0.001939058 : 0.001929058 sec 0.000100000 : 0.001938105 : 0.001838105 sec 0.001000000 : 0.002938032 : 0.001938032 sec 0.010000000 : 0.011937141 : 0.001937141 sec 0.100000000 : 0.101919174 : 0.001919174 sec
繰り返すと1ms、2msの2パターンの誤差がでる。
なぜそんなことになるのか。
ここは伊藤直也ばりのカーネル解析で・・・すみません、今はできません。
MacBook
air:timer mikeda$ ./nanosleep_check 指定 停止 誤差 0.000000001 : 0.000029087 : 0.000029086 sec 0.000000010 : 0.000018835 : 0.000018825 sec 0.000000100 : 0.000018120 : 0.000018020 sec 0.000001000 : 0.000017881 : 0.000016881 sec 0.000010000 : 0.000122070 : 0.000112070 sec 0.000100000 : 0.000231028 : 0.000131028 sec 0.001000000 : 0.001104832 : 0.000104832 sec 0.010000000 : 0.010083914 : 0.000083914 sec 0.100000000 : 0.100172997 : 0.000172997 sec
やっぱりMacBookのほうが精度がいい。