0. 概要
Cygwinなど、発生する環境は限られている可能性は高いが一応注意として記載。
諸事情でusleep(1000)(==1msec待ち)*1000回による1秒待ちのロジックを組んだ所、思った以上にずれた。
後述の環境で、1秒待ちが、17-18秒待ちとなった。
usleep(1000000)*1回では、概ね1秒で復帰するので、関数呼び出しコストで誤差が大きくなるようである。
※ usleep(1000000)をエラーとするシステムもあるので注意
https://linuxjm.osdn.jp/html/LDP_man-pages/man3/usleep.3.html
1. 検証ロジック
int main(int argc, char **argv)
{
int i = 0;
struct timeval startTime;
struct timeval endTime;
int interval = atoi(argv[1]);
int waitcnt = atoi(argv[2]);
gettimeofday(&startTime, NULL);
for(i = 0; i < waitcnt; i++) {
usleep(interval);
}
gettimeofday(&endTime, NULL);
printf("Time - from gettimeofday...\n");
printf("[START]\n");
printf(" sec : %ld\n", startTime.tv_sec);
printf(" usec : %ld\n", startTime.tv_usec);
printf("[END]\n");
printf(" sec : %ld\n", endTime.tv_sec);
printf(" usec : %ld\n", endTime.tv_usec);
printf("[DIFF(about)]\n");
printf(" sec : %ld\n", (endTime.tv_sec + endTime.tv_usec/1000000) - (startTime.tv_sec + startTime.tv_usec/1000000));
printf(" usec : %ld\n", (endTime.tv_sec*1000000 + endTime.tv_usec) - (startTime.tv_sec*1000000 + startTime.tv_usec));
printf(" msec : %ld\n", (endTime.tv_sec*1000 + endTime.tv_usec/1000) - (startTime.tv_sec*1000 + startTime.tv_usec/1000));
return 0;
}
2. 検証結果
usleep(1000)*1000
sec | msec | usec | |
---|---|---|---|
1 | 18 | 17556 | 17556441 |
2 | 17 | 17004 | 17004605 |
3 | 17 | 16920 | 16919761 |
4 | 17 | 17053 | 17053231 |
5 | 17 | 16935 | 16934642 |
usleep(1000000)*1
sec | msec | usec | |
---|---|---|---|
1 | 1 | 1008 | 1008031 |
2 | 1 | 999 | 998874 |
3 | 1 | 1004 | 1003806 |
4 | 1 | 1014 | 1014538 |
5 | 1 | 1008 | 1008308 |
3. 検証環境
OS : Windows 10
CPU : 11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz
RAM : 16.0 GB
Cygwin 64bit 上
※ その他、libcのバージョン等も影響する可能性はある。
※ ほぼ同等スペックの別PCでも概ね同じ結果だった。
補足:usleep()以外にかかる時間
usleep()以外にかかる時間は、usec以下の様子なので誤差として無視した。