63
|
1 2008-02-17 Wataru MIYAGUNI <gongo@cr.ie.u-ryukyu.ac.jp>
|
|
2
|
80
|
3 * Todo: 悩んでる所
|
|
4
|
|
5
|
63
|
6 * fix: kernel/ppe/HTask.cpp
|
|
7 今まで、manager->create_task で生成したタスクは
|
|
8
|
|
9 - dependency の設定
|
|
10 manager->set_task_depend(master, slave) // slave は master を待つ
|
|
11
|
|
12 - 実行キューへの追加
|
|
13 manager->spawn_task(master);
|
|
14 manager->spawn_task(slave);
|
|
15
|
|
16 と、manager を介してやっていました。
|
|
17 まあそれでもいいんだけど、特に dependency の所は
|
|
18 どっちがどっちを待つのかってのは、API見るだけじゃわからない。
|
|
19 そこで、Task (HTask のこと) に、上二つに対応するような
|
|
20
|
|
21 void set_depend(HTaskPtr) と void spawn(void) を追加しました。
|
|
22
|
|
23 - Usage
|
|
24 slave->set_depend(master); // slave は master を待つ
|
|
25 slave->spawn(); // slave をキューへ追加
|
|
26
|
|
27 結局は、それぞれの関数の中では、上の set_task_depend とかを
|
|
28 呼んでるんだけど、ユーザ側からするとこの方がわかりやすいと思います。
|
|
29
|
56
|
30 2008-02-16 Wataru MIYAGUNI <gongo@cr.ie.u-ryukyu.ac.jp>
|
|
31
|
|
32 * tag: beta3
|
|
33 ダブルバッファリングを追加し、まあなんとか動いてるんじゃない?って
|
|
34 ところまでですが、所詮 Fifo バージョンなので、
|
|
35 そろそろ Cell を書き上げて、並列にちゃんと動いてるか確かめないとね
|
|
36
|
|
37 * add: kernel/ppe/DmaBuffer.cpp
|
|
38 ダブルバッファリング用に作ったんだけど、
|
|
39 せっかくなので、DMA は、このオブジェクト(が持つ二つの領域)でしか
|
|
40 行えないようにする。ってのでどうでしょう。って話を先生としました。
|
|
41 並列処理だし、ダブルバッファリングがデフォでいいでしょう。
|
|
42 というか、したくなければ swap_buffer とかしなければおk。
|
|
43
|
62
|
44 -Usage
|
|
45 DmaBuffer *buffer = manager->allocate(sizeof(SceneGraphPack));
|
|
46
|
|
47 今までと違い、create_task の in_addr と out_addr には
|
|
48 DmaBuffer をいれてください。ユーザが自分で malloc/new したやつは
|
|
49 エラーを出すようにしてる(seg faultだけどね!)
|
|
50 汚いソースだが、実際に使ってる様子は Test/simple_render の
|
|
51 viewer.cpp で使ってます。sgp_buff と pp_buff ってやつね。
|
|
52
|
|
53 もうすこしユーザに優しいAPIを作りたい・・・
|
|
54
|
29
|
55 2008-02-11 Wataru MIYAGUNI <gongo@cr.ie.u-ryukyu.ac.jp>
|
|
56
|
|
57 * add: Test/simple_render
|
|
58 chiaki の DataPack を使った Cube の表示プログラム。
|
|
59 簡単に DataPack を TaskManager の scheduler (SpeManager) に渡して
|
|
60 処理してコピーして、を繰り返してるだけなんだけど
|
|
61 まあ動いてる気がするのでいいんじゃないでしょうか。
|
|
62
|
56
|
63
|
23
|
64 2008-02-10 Wataru MIYAGUNI <gongo@cr.ie.u-ryukyu.ac.jp>
|
|
65
|
|
66 * tag: beta1
|
|
67 この状況だと、できることよりもできないことを書くべき?違うか。
|
|
68
|
|
69 - task (親) 中で task (子) を生成することはできない
|
|
70 正確には「生成はできる」だけど、その 子task が
|
|
71 親task に依存している別の task を無視して動くので
|
|
72 ちゃんとした結果にならないと。
|
|
73 8日の Todo にも書いてあるけど、今の実装では
|
|
74 task が task を生成することを想定してない感じなので。
|
|
75 完全に spe 用にのみ狙いを絞った実装であって
|
|
76 OS って言えない実装であるからして、書き直すの?
|
|
77 全ての関数を task しようとするとこうなる訳で、
|
|
78 ある部分だけやるってのはまあできるんだろうけど、うーん。
|
|
79
|
|
80 - chiaki の simple_render が動かない
|
24
|
81 (追記) 解決しました
|
|
82 単に read/write buffer のサイズが足りないだけだった。アホスwww
|
|
83 まあ辱めの為の下は残しておこう
|
56
|
84
|
23
|
85 まだ cvs に commit してないけど、chiaki が書いた、
|
|
86 DataPack 対応の simple_render に TasKManager を組み込んでみた。
|
|
87 といっても、OSっぽく書いたんじゃなく、今は
|
|
88 update_sgp と create_pp だけを task 化してみた。
|
|
89 でまあ動いてるような気はするけど、ものすっごい malloc 系の warning が。
|
|
90 時々長く動くよねみたいな感じになってしまっている。
|
|
91 TaskManager が悪いのか、simple_render が悪いのか。
|
|
92 この TaskManager、ある部分での malloc 系の問題に敏感だなあ。
|
|
93 まあそうでなかったらバグの探しようも無いし、良いっちゃー良いんだが。
|
56
|
94
|
|
95
|
16
|
96 2008-02-08 Wataru MIYAGUNI <gongo@cr.ie.u-ryukyu.ac.jp>
|
|
97
|
|
98 * add: kernel/ppe/SymTable.cpp
|
|
99 今まで func[] = {add, sum, ...}
|
|
100 とかやってかっこわるい言われまくってたので
|
|
101 話し合いの通り Symbol Table みたいなものを作ることに
|
|
102
|
|
103 // 疑似コードね
|
|
104 struct sym_table {
|
|
105 char *sym; // シンボル
|
|
106 void *address; // シンボルが示すアドレス
|
|
107 } sym_table[] = {{"Sum", &Sum} , {"Draw", &draw}};
|
|
108
|
|
109 int fd = get_fd("Sum");
|
|
110 void *addr = get_address(fd);
|
56
|
111
|
16
|
112 table には "Sum" と "Draw" っていう二つのシンボルが登録されている。
|
|
113 例えば、ユーザ(カーネル?)が "Sum" ってシンボルにアクセスしたい場合、
|
|
114 まずは get_fd で "Sum" に対する、file descripter を返す。
|
|
115 ユーザは、その fd に従って get_address を取得することが出来る。
|
|
116 TaskManager 的な使い方をするなら
|
|
117
|
|
118 // 俺は今、Draw 関数を使うタスクを生成したい
|
|
119 int fd = manager->open("Draw");
|
|
120 manager->create_task(fd, size, in, out, func);
|
|
121 manager->open では get_fd と同じ使い方です。
|
|
122
|
|
123 まだ改良の余地ありそうですが、今は動いてるってことで。
|
|
124
|
|
125
|
|
126 - 補足
|
|
127 なぜ file descripter と表すか
|
|
128
|
|
129 OS の昨日として、 fopen とかと同じ使い方もできるじゃない!
|
|
130
|
56
|
131
|
16
|
132 * Todo: task が task を生成する際の処理
|
|
133 今まで、 task が行う作業は、演算のみを行うような
|
|
134 単純な実装に決め打ちされているわけです。
|
|
135 しかし、OS なんかだと、タスク中から別のタスクを生成するとか
|
|
136 ありありだと思われる。てか今のテストプログラムでなった。
|
|
137
|
|
138 Test/Sum にあるプログラムで使われるタスク
|
|
139
|
|
140 - init2 // 貧相な名前ですまない
|
|
141 演算する数値とかバッファの初期化
|
|
142
|
|
143 - sum1
|
|
144 ある範囲の整数 (i から i+16 とか) の総和
|
|
145
|
|
146 - sum2
|
|
147 sum1 で求められた、複数の範囲の総和を一つにまとめる
|
|
148 (ex. 複数の sum1 が 1->16, 17->32, 33->48 の総和を計算し、
|
|
149 sum2 で 上の3つの総和を計算する
|
|
150 要は 1->48 の総和を分割するっていうプログラムね
|
|
151
|
|
152 - finish
|
|
153 sum2 で求まった値を表示
|
|
154
|
|
155 この Sum というプログラム、というか OS と言おう。SumOS ね。
|
|
156 SumOS は最初に TaskManager (所謂 kernel) を起動し、
|
|
157 init を起動する。init では、予め決められたタスクである
|
|
158 init2 と finish の二つのタスクを create して登録する。
|
|
159 init2 と finish には依存関係がある (init2 が終わったら finish)
|
|
160 init2 の中で、sum1 と sum2 というタスクが作られる。
|
|
161 sum1 と sum2 にも依存関係はある (sum1 が終わったら sum2)
|
56
|
162
|
16
|
163 今の実装だと、タスクが終了して初めて次のタスクへ行く。
|
|
164 まあ当たり前なんだけど、例えばそのタスクの中で
|
|
165 新たにタスクが作られた場合、そのタスクが終了するまでは
|
|
166 実行されなくなってしまう。
|
|
167 でまあ、今は、manager->create_task される度に
|
|
168 manager->run とかして、無理やり起動してる訳さ。
|
|
169 何が無理矢理かっていうと、scheduler の役目をしている
|
|
170 SpeManager (これも名前変えないと) を2度呼び出してる訳。
|
|
171 つまり、タスク中でタスクを作る度に、SpeManager オブジェクトを
|
|
172 new してるわけさ。いいのか?いや、動いてるけどね?
|
|
173
|
|
174 ちなみに、Cell version だと spe が勝手に取っていってくれるから
|
|
175 大丈夫かなと思いつつ、もし spe を1つしか使わない設定だったら微妙。
|
|
176
|
|
177 要するに、タスク中でタスクが作られる場合の処理を考えないとね。
|
56
|
178
|
13
|
179 2008-02-07 Wataru MIYAGUNI <gongo@cr.ie.u-ryukyu.ac.jp>
|
|
180
|
|
181 * memo: プログラミングの姿勢
|
|
182 scheduler とか、task の管理をする部分は
|
|
183 kernel programing のつもりで、
|
|
184 example とか、task に割り当てる処理を決めたりする部分は
|
|
185 user programing のつもりで。
|
|
186
|
|
187 それぞれ違った視点で見る必要がある
|
|
188
|
|
189 * memo: OS というもの
|
|
190 OS 起動の流れ
|
|
191
|
|
192 - PC の電源を入れる
|
|
193 - BIOS が立ち上がる (OpenFirmWare, EFI, BIOS)
|
|
194 - 起動デバイスをチェック (優先度とか種類とか)
|
|
195 - 起動デバイスから Boot loader を起動
|
|
196 + BIOS によって、認識できるファイルシステムが違う(だっけ?)
|
|
197 + ファイルシステムのどこに Boot Loader があるか知っている
|
56
|
198 + grub, grub2, lilo, kboot などがある
|
13
|
199 - Boot Loader が kernel を起動
|
|
200 + ネットワークブートの場合、TCP/IP や
|
|
201 ネットワークデバイス(イーサとか?)のドライバを持ってる必要がある
|
|
202 - kernel は、最初に scheduler を起動する
|
|
203 - scheduler の初期化 (init を呼ぶ?)
|
|
204 - init では、事前?に設定されているスクリプトとかを呼ぶ
|
|
205 + linux とかだと /etc/rc にあるやつを init が呼ぶ
|
|
206 - login form が起動
|
|
207
|
|
208 補足 こっからユーザ
|
|
209 - login する
|
|
210 - shell を呼ぶ
|
|
211 + login shell かどうか確かめる
|
|
212 - ユーザに設定されてる起動スクリプト?を実行
|
|
213 - 晴れてログイン
|
|
214
|
10
|
215 2008-02-06 Wataru MIYAGUNI <gongo@cr.ie.u-ryukyu.ac.jp>
|
|
216
|
|
217 * kernel/spe/*.cpp: new と placement new
|
|
218 現在、spe kernel のタスクは、切り替わる毎に
|
|
219 new/delete を繰り返しています。今はこれでいいんだけど、
|
|
220 速度的にも、いずれは直さないといけないと思うわけで。
|
|
221 で、予め allocate された領域を利用した placement new を使えば
|
|
222 new よりもそれなりに早くなるっぽい。
|
|
223 例題として、与えられた回数分 new/delete を繰り返すプログラムと、
|
|
224 同じ回数分、placement new したときの速度の比較
|
|
225
|
|
226 for (int i = 0; i < num; i++) {
|
|
227
|
|
228 < task = new Task;
|
|
229 < task->init(i);
|
|
230 < task->printID();
|
|
231 < delete task;
|
|
232 ---
|
|
233 > task = new(buff) Task; // buff = malloc(BUFF_SIZE);
|
|
234 > task->init(id);
|
|
235 > task->printID(id);
|
|
236 }
|
56
|
237
|
10
|
238 placement new では、delete の必要は無い。
|
|
239 その中で新たに allocate してるなら必要かもしれないが。
|
|
240 速度比較は以下。no_new が placement new で、ln_new が new/delete 。
|
|
241
|
|
242 % ./a.out 10 // 10 回
|
|
243 no_new: time: 0.012135(msec)
|
|
244 ln_new: time: 0.003572(msec)
|
|
245
|
|
246 % ./a.out 100
|
|
247 no_new: time: 0.022453(msec)
|
|
248 ln_new: time: 0.018989(msec)
|
|
249
|
|
250 % ./a.out 1000
|
|
251 no_new: time: 0.115277(msec)
|
|
252 ln_new: time: 0.136335(msec)
|
|
253
|
|
254 % ./a.out 10000
|
|
255 no_new: time: 1.056156(msec)
|
|
256 ln_new: time: 1.322709(msec)
|
|
257
|
|
258 % ./a.out 100000
|
|
259 no_new: time: 10.622221(msec)
|
|
260 ln_new: time: 13.362414(msec)
|
|
261
|
|
262 % ./a.out 1000000
|
|
263 no_new: time: 109.436496(msec)
|
|
264 ln_new: time: 136.956872(msec)
|
|
265
|
|
266 10、100 回だと負けてるが、まあ無視しよう(ぇ
|
|
267 回数が多くなるにつれて、ほんの少しだが no_new が勝ってる。
|
|
268 どうなんだろうね。ちなみに printID を無くすと
|
|
269
|
|
270 % ./a.out 1000000
|
|
271 no_new: time: 0.008512(msec)
|
|
272 ln_new: time: 27.100296(msec)
|
|
273
|
|
274 I/O に左右され過ぎ。まあそんなもんだろうけどさ。
|