Linux のしくみの プロセススケジューラの章の内容、まあそうですよね...と思いつつ実際に手元マシンで実験してみたことはなかったのでやってみました。ついでに、たまたま気が向いたので結果をグラフ化してまとめておきました。gnuplot 使うの 4 年ぶり以上だ...。
[amazon template=wishlist&asin=477419607X]
taskset
コマンドで実行する論理 CPU を指定する#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <time.h> #define LOOP_COUNT 100000UL #define NSEC_PER_SEC 1000000000UL static inline void loop() { long i; for(i = 0; i < LOOP_COUNT; i++); } static inline void print_progress(long elapsed_time_nsec, int pid, int progress) { printf("%ld\t%d\t%d\n", elapsed_time_nsec, pid, progress); } static inline long diff_nsec(struct timespec before, struct timespec after) { return (after.tv_sec * NSEC_PER_SEC + after.tv_nsec) - (before.tv_sec * NSEC_PER_SEC + before.tv_nsec); } static inline void child_function(int id, struct timespec before) { struct timespec after; int i; for (i = 0; i < 100; i++) { clock_gettime(CLOCK_MONOTONIC, &after); print_progress(diff_nsec(before, after), id, i); loop(); } clock_gettime(CLOCK_MONOTONIC, &after); print_progress(diff_nsec(before, after), id, 100); } int main(int argc, char *argv[]) { int status = EXIT_FAILURE; if (argc != 2) { fprintf(stdout, "Usage: %s nproc\n", argv[0]); exit(1); } int nproc = atoi(argv[1]); if (nproc < 1) { fprintf(stdout, "Argument: invalid nproc %s nproc\n", argv[0]); exit(1); } struct timespec before; clock_gettime(CLOCK_MONOTONIC, &before); int i; for (i = 0; i < nproc; i++) { pid_t pid = fork(); if (pid < 0) { fprintf(stdout, "error\n"); exit(1); } else if (pid == 0) { // child process child_function(i, before); exit(0); } } // parent process int j; for (j = 0; i < nproc; j++) { wait(NULL); } printf("\n"); exit(0); }
taskset -c 0 ./test 1 taskset -c 0 ./test 2 taskset -c 0 ./test 4
throughput: 1 process / 33615570 nsec = 29.748 process / sec latency(id=0): 3.36x10^7 nsec
throughput: 2 process / 64405632 nsec = 31.053 process / sec latency(id=0): 5.31x10^7 nsec latency(id=1): 5.40x10^7 nsec latency(ave.): 5.36x10-7 nsec
throughput: 4 process / 130027521 nsec = 30.762 process / sec latency(id=0): 8.67x10^7 nsec latency(id=1): 10.9x10^7 nsec latency(id=2): 8.71x10^7 nsec latency(id=3): 10.8x10^7 nsec latency(ave.): 9.77x10^7 nsec
プロセス数 | スループット (process/sec) | 平均レイテンシ (x10^7 [nsec]) |
---|---|---|
1 | 29.748 | 3.36 |
2 | 31.053 | 5.36 |
4 | 30.762 | 9.77 |
nice
などで優先度操作をしなければ...)nice
は デフォルトを 0 として、 [-20, 20] の範囲でプロセスに優先度をつけ、CPU 時間はそれに応じて割り振られる以下のような環境で実験してみる(この実験結果は前のマシンとは異なるもので実験しているので、スループットやレイテンシは比較しないでください)
$ grep proc /proc/cpuinfo processor : 0 processor : 1 processor : 2
ウェブ界隈でエンジニアとして労働活動に励んでいる @gomi_ningen 個人のブログです