nanosleep の精度
nanosleep が pthread のスケジューリングポリシーと優先度で違いが出るか実験。結果は、変わらない(当たり前?)。それより、 10 ms の nanosleep からオーバヘッド 1ms 程度以内 で復帰できるとは最近の Linux は精度があがってる。
#include <stdio.h> #include <stdlib.h> #include <sys/time.h> #include <time.h> #include <pthread.h> #define NUM_OF_REPEAT 10 #define BUF_SIZE 1024 /* milli sec */ #define TIMEOUT 10 #define NELEMS(array) (sizeof(array) / sizeof(array[0])) typedef struct ThreadTable { int policy; int priority; } ThreadTable; int sprint_msec(char *buf) { struct timeval tv; struct tm tm; int len; gettimeofday(&tv, NULL); localtime_r(&(tv.tv_sec), &tm); len = sprintf(buf, "%d [sec], %03ld [msec], %03ld [usec]\n", (int)tv.tv_sec, tv.tv_usec / 1000, tv.tv_usec % 1000); return len; } /* milli sec */ int calc_elapsed(struct timeval *tv_before, struct timeval *tv_after) { int sec; int usec; sec = tv_after->tv_sec - tv_before->tv_sec; usec = tv_after->tv_usec - tv_before->tv_usec; return (sec * 1000) + (usec / 1000); } char *get_policy_str(int num) { switch (num) { case SCHED_OTHER: return "SCHED_OTHER"; case SCHED_FIFO: return "SCHED_FIFO"; case SCHED_RR: return "SCHED_RR"; default: return "Unknown schedule policy"; break; } } void *timer_thread(void *no_use) { char *p; struct timeval tv_before; struct timeval tv_after; struct timespec ts; int i; int sum; char buf[BUF_SIZE]; int policy; struct sched_param param; p = buf; sum = 0; ts.tv_sec = 0; ts.tv_nsec = TIMEOUT * 1000 * 1000; p += sprint_msec(p); for (i = 0; i < NUM_OF_REPEAT; i++) { gettimeofday(&tv_before, NULL); nanosleep(&ts, NULL); gettimeofday(&tv_after, NULL); sum += calc_elapsed(&tv_before, &tv_after); p += sprint_msec(p); } /* print info */ if (0 != pthread_getschedparam(pthread_self(), &policy, ¶m)) { perror("pthread_getschedparam"); pthread_exit(NULL); } printf("%s(%d) priority %d\n", get_policy_str(policy), policy, param.sched_priority); printf("%s", buf); printf("average %.3f [msec]\n\n", 1.0 * sum / NUM_OF_REPEAT); pthread_exit(NULL); return NULL; } int main(int argc, char *argv[]) { int i; pthread_t thread; pthread_attr_t attr; struct sched_param sched_param; ThreadTable thread_table[] = { {SCHED_OTHER, 0}, {SCHED_FIFO, 1}, {SCHED_FIFO, 50}, {SCHED_FIFO, 99}, {SCHED_RR, 1}, {SCHED_RR, 5}, {SCHED_RR, 99}, }; for (i = 0; i < NELEMS(thread_table); i++) { pthread_attr_init(&attr); if (0 != pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED)) { perror("pthread_attr_setinheritsched"); exit(1); } if (0 != pthread_attr_setschedpolicy(&attr, thread_table[i].policy)) { perror("pthread_attr_setschedpolicy"); exit(1); } pthread_attr_getschedparam(&attr, &sched_param); sched_param.sched_priority = thread_table[i].priority; if (0 != pthread_attr_setschedparam(&attr, &sched_param)) { perror("pthread_attr_setschedparam"); exit(1); } if (0 != pthread_create(&thread, &attr, &timer_thread, NULL)) { fprintf(stderr, "error : pthread_create\n"); exit(1); } pthread_join(thread, NULL); } return 0; }
SCHED_OTHER(0) priority 0 1264078401 [sec], 389 [msec], 798 [usec] 1264078401 [sec], 401 [msec], 502 [usec] 1264078401 [sec], 413 [msec], 505 [usec] 1264078401 [sec], 425 [msec], 500 [usec] 1264078401 [sec], 437 [msec], 500 [usec] 1264078401 [sec], 449 [msec], 501 [usec] 1264078401 [sec], 461 [msec], 498 [usec] 1264078401 [sec], 473 [msec], 527 [usec] 1264078401 [sec], 485 [msec], 497 [usec] 1264078401 [sec], 497 [msec], 499 [usec] 1264078401 [sec], 509 [msec], 495 [usec] average 11.100 [msec] SCHED_FIFO(1) priority 1 1264078401 [sec], 510 [msec], 058 [usec] 1264078401 [sec], 521 [msec], 538 [usec] 1264078401 [sec], 533 [msec], 517 [usec] 1264078401 [sec], 545 [msec], 492 [usec] 1264078401 [sec], 557 [msec], 492 [usec] 1264078401 [sec], 569 [msec], 490 [usec] 1264078401 [sec], 581 [msec], 489 [usec] 1264078401 [sec], 593 [msec], 488 [usec] 1264078401 [sec], 605 [msec], 494 [usec] 1264078401 [sec], 617 [msec], 487 [usec] 1264078401 [sec], 629 [msec], 487 [usec] average 11.000 [msec] SCHED_FIFO(1) priority 50 1264078401 [sec], 630 [msec], 566 [usec] 1264078401 [sec], 642 [msec], 500 [usec] 1264078401 [sec], 654 [msec], 485 [usec] 1264078401 [sec], 666 [msec], 484 [usec] 1264078401 [sec], 678 [msec], 483 [usec] 1264078401 [sec], 690 [msec], 481 [usec] 1264078401 [sec], 702 [msec], 484 [usec] 1264078401 [sec], 714 [msec], 482 [usec] 1264078401 [sec], 726 [msec], 482 [usec] 1264078401 [sec], 738 [msec], 479 [usec] 1264078401 [sec], 750 [msec], 481 [usec] average 11.000 [msec] SCHED_FIFO(1) priority 99 1264078401 [sec], 750 [msec], 669 [usec] 1264078401 [sec], 762 [msec], 515 [usec] 1264078401 [sec], 774 [msec], 480 [usec] 1264078401 [sec], 786 [msec], 478 [usec] 1264078401 [sec], 798 [msec], 477 [usec] 1264078401 [sec], 810 [msec], 480 [usec] 1264078401 [sec], 822 [msec], 477 [usec] 1264078401 [sec], 834 [msec], 474 [usec] 1264078401 [sec], 846 [msec], 473 [usec] 1264078401 [sec], 858 [msec], 477 [usec] 1264078401 [sec], 870 [msec], 471 [usec] average 11.000 [msec] SCHED_RR(2) priority 1 1264078401 [sec], 870 [msec], 668 [usec] 1264078401 [sec], 882 [msec], 487 [usec] 1264078401 [sec], 894 [msec], 468 [usec] 1264078401 [sec], 906 [msec], 469 [usec] 1264078401 [sec], 918 [msec], 465 [usec] 1264078401 [sec], 930 [msec], 467 [usec] 1264078401 [sec], 942 [msec], 468 [usec] 1264078401 [sec], 954 [msec], 464 [usec] 1264078401 [sec], 966 [msec], 462 [usec] 1264078401 [sec], 978 [msec], 461 [usec] 1264078401 [sec], 990 [msec], 460 [usec] average 11.000 [msec] SCHED_RR(2) priority 5 1264078401 [sec], 991 [msec], 557 [usec] 1264078402 [sec], 003 [msec], 479 [usec] 1264078402 [sec], 015 [msec], 462 [usec] 1264078402 [sec], 027 [msec], 460 [usec] 1264078402 [sec], 039 [msec], 459 [usec] 1264078402 [sec], 051 [msec], 457 [usec] 1264078402 [sec], 063 [msec], 457 [usec] 1264078402 [sec], 075 [msec], 455 [usec] 1264078402 [sec], 087 [msec], 454 [usec] 1264078402 [sec], 099 [msec], 453 [usec] 1264078402 [sec], 111 [msec], 453 [usec] average 11.100 [msec] SCHED_RR(2) priority 99 1264078402 [sec], 111 [msec], 613 [usec] 1264078402 [sec], 123 [msec], 465 [usec] 1264078402 [sec], 135 [msec], 461 [usec] 1264078402 [sec], 147 [msec], 454 [usec] 1264078402 [sec], 159 [msec], 451 [usec] 1264078402 [sec], 171 [msec], 449 [usec] 1264078402 [sec], 183 [msec], 447 [usec] 1264078402 [sec], 195 [msec], 446 [usec] 1264078402 [sec], 207 [msec], 447 [usec] 1264078402 [sec], 219 [msec], 445 [usec] 1264078402 [sec], 231 [msec], 444 [usec] average 11.000 [msec]