2009年5月26日火曜日

20090519のHomework

1. Take last week's memory copy program, and modify it to fork() to a certain depth, then have each one of the processes time the copy of a certain amount of memory. Your program should take three arguments, the depth, the amount of memory to copy, and the number of times to copy the memory. Ideally, the amount of memory to copy should be large enough to require several seconds, but that's not practical, so have it repeat the copy some number of times. For example, fork five processes, malloc() ten megabytes each, and have the processes copy that memory one hundred times.

A.Run the program with a depth of one, and report how long it takes. Repeat this program twenty-five times and report the average and the individual times.
[プログラム]
1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7
8 double gettimeofday_sec();
9 void usage();
10 void exec_fork_and_copy(int, int, int);
11 void copy_mem(int *, int *, int, int);
12
13 int
14 main(int argc, char* argv[])
15 {
16 int size = 0;
17 int count = 0;
18 int depth = 0;
19 int i = 0;
20 int pid = 0;
21 char ch;
22 pid_t start_process_id, stop_process_id;
23 double start_time, stop_time;
24
25 //
26 // check the number of argument
27 //
28 if (argc != 7) {
29 usage();
30 }
31
32 //
33 // check the option
34 //
35 while ((ch = getopt(argc, argv, "d:b:t:")) != -1) {
36 switch (ch) {
37 case 'd': // set depth
38 depth = atoi(optarg);
39 break;
40 case 'b': // set the amount of memory to copy
41 size = atoi(optarg)*1000000; // M
42 break;
43 case 't': // set the number of times to copy the memory
44 count = atoi(optarg);
45 break;
46 default:
47 fprintf(stderr, "unknown option\n");
48 usage();
49 }
50 }
51 start_process_id = getpid();
52
53 fprintf(stderr, "process_id: %d\ndepth: %d\nmemory size: %d\ntimes: %d\n", start_process_id, depth, size, count);
54 // exit(0);
55
56 // get start time
57 start_time = gettimeofday_sec();
58
59 //
60 // execution
61 //
62 exec_fork_and_copy(depth, size, count);
63
64
65 stop_process_id = getpid();
66 // print result
67 if (start_process_id == stop_process_id) {
68 // get stop time
69 stop_time = gettimeofday_sec();
70
71 printf("時間:%10.30f\n", stop_time - start_time);
72 }
73 }
74
75 void
76 exec_fork_and_copy(int depth, int size, int count)
77 {
78 int i;
79 int status;
80 pid_t pid=0;
81 int *src;
82 int *dst;
83
84 for (i = 0; i < pid =" fork())" src =" (int" dst =" (int" i="0;" 107="" 108="" 109="" 110="" free="" 111="" 112="" 113="" 114="" 115="" double="" 116="" 117="" 118="" struct="" timeval="" 119="" 120="" return="" tv_sec="" 121="" 122="" 123="" void="" 124="" 125="" 126="" 127="" depth="" size="" n="" 128="" 129="" 130="" mempro="" d="" 1="" b="" 10="" t="" 100="">
1 : 時間:0.674799919128417968750000000000
2 : 時間:0.697927951812744140625000000000
3 : 時間:0.734071969985961914062500000000
4 : 時間:0.722994804382324218750000000000
5 : 時間:0.702398061752319335937500000000
6 : 時間:0.687880992889404296875000000000
7 : 時間:0.769035100936889648437500000000
8 : 時間:0.713932037353515625000000000000
9 : 時間:0.675138950347900390625000000000
10: 時間:0.667946100234985351562500000000
11: 時間:0.682356834411621093750000000000
12: 時間:0.728009939193725585937500000000
13: 時間:0.769045829772949218750000000000
14: 時間:0.690872907638549804687500000000
15: 時間:0.703732013702392578125000000000
16: 時間:0.657273054122924804687500000000
17: 時間:0.692090988159179687500000000000
18: 時間:0.687263965606689453125000000000
19: 時間:0.678195953369140625000000000000
20: 時間:0.692916870117187500000000000000
21: 時間:0.701704025268554687500000000000
22: 時間:0.674097061157226562500000000000
23: 時間:0.679100990295410156250000000000
24: 時間:0.705204010009765625000000000000
25: 時間:0.666203975677490234375000000000

平均: 0.6977

B.
Now run the program with a depth of five. Again, repeat at least five times and report the average. Is the average higher than five times the depth one case? Why?
[実行]
./mempro -d 5 -b 10 -t 100

[実行結果]
1: 時間:3.502972126007080078125000000000
2: 時間:3.525238990783691406250000000000
3: 時間:3.549910068511962890625000000000
4: 時間:3.512364149093627929687500000000
5: 時間:3.534419059753417968750000000000

平均 : 3.5244

Aの5回の平均:3.4886
Bの方が時間が長いのは子プロセスをコピーする時間が必要なためであると考えられる

C. Plot the density function for the execution time. (You should have twenty-five data points here for copying a gigabyte of memory each, for the depth one and depth five cases.) Is there more variability in the depth five case?





2.Run one copy of your program at the normal priority, and at the same time a second copy at lower priority, e.g. by using nice. Does the first one completely monopolize the CPU until it is finished?
[プログラム(変更箇所のみ)]
86 if(fork() == 0) {
87 cpid = getpid();
88 fprintf(stderr,"priority 20 cpid : %d process start!\n", cpid);
89 nice(20);
90 copy_mem(src, dst, size, count);
91 fprintf(stderr, "pid : %d i: %d\n", cpid, i);
92 } else if (fork() == 0) {
93 cpid = getpid();
94 fprintf(stderr,"priority 10 cpid : %d process start!\n\n", cpid);
95 nice(10);
96 copy_mem(src, dst, size, count);
97 fprintf(stderr, "pid : %d i: %d\n", cpid, i);
98 }

[実行]
./mempro_pri -d 1 -b 10 -t 10
[実行結果]
depth: 1
memory size: 10000000
times: 100
priority 20 pid : 11652 process start!
priority 10 pid : 11653 process start!

pid : 11653 priority 10 stop!
pid : 11652 priority 20 stop!

3.Find and report the time quantum for your particular system.
Linuxのカーネルは
優先度を用いてプロセスを時分割で実行する「O(1)スケジューラ」を採用している。
またCPUが割り当てられてプロセスが実行できる時間をクォンタムという。


・O(1)スケジューラ以外のスケジューラを使う方法
プログラムのmain()関数で
policy = SCHED_FIFO;
と書いてポリシーを変更する

セットできる値としては
SCHED_FIFO:First Input First Output
SCHED_RR:ラウンドロビン
SCHED_OTHER:優先度付き時分割
SCHED_BATCH:バッチ

これによってスケジューリングを変えることが出来る

4.Schedule a meeting with me (voice or in person) to discuss your project by the end of next week.
有田、中村で話し合った結果、
5/28 午前〜16:00
5/29 一日中
に面談を行うことが可能です。
よろしくお願いします。

0 件のコメント:

コメントを投稿