Mercurial > hg > Game > Cerium
changeset 104:226c743d07c6
*** empty log message ***
author | gongo |
---|---|
date | Mon, 03 Mar 2008 17:21:20 +0900 |
parents | 63c598f1cf0f |
children | 3e331f7576a1 |
files | TaskManager/ChangeLog TaskManager/Changelog |
diffstat | 2 files changed, 21 insertions(+), 287 deletions(-) [+] |
line wrap: on
line diff
--- a/TaskManager/ChangeLog Mon Mar 03 17:21:20 2008 +0900 +++ b/TaskManager/ChangeLog Mon Mar 03 17:21:20 2008 +0900 @@ -1,3 +1,24 @@ +2008-03-03 Wataru MIYAGUNI <gongo@cr.ie.u-ryukyu.ac.jp> + + * memo: 最適化の結果 + ppe/spe ともに最適化なしの場合 + 263.444 FPS + + ppe だけ -O9 で最適化 + 317.425 FPS + + spe だけ -O9 で最適化 + 812.539 FPS + + ppe/spe ともに -O9 で最適化 + 1610.58 FPS (吹いた + + + 最初、ダブル最適化の画像を見た時の + あまりの早さにびびった。 + 逆に「こ、これはバグか!?」と思った + + 2008-02-28 Wataru MIYAGUNI <gongo@cr.ie.u-ryukyu.ac.jp> * kernel/ppe/BufferManager.cpp: remove_taskQueue_all()
--- a/TaskManager/Changelog Mon Mar 03 17:21:20 2008 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,287 +0,0 @@ -2008-02-28 Wataru MIYAGUNI <gongo@cr.ie.u-ryukyu.ac.jp> - - * kernel/ppe/BufferManager.cpp: remove_taskQueue_all() - taskQueue の create と free が釣り合って無くて、 - queue が足りなくなる -> extend_pool -> 足りなく(ry - ってのを繰り返してメモリ的なセグメンテーションフォルとが出て - なんでかなと思ったら、task->wait_me を消去してなかった。 - task->wait_i は notify(ry で削除されるんだけど、 - task->wait_me は、notify(ry に渡した後ほったらかしだった。 - ってことで、wait_me を全消しする関数を作りましたとさ。 - 気持ち速度が増した気がする。気ね。 - - -2008-02-17 Wataru MIYAGUNI <gongo@cr.ie.u-ryukyu.ac.jp> - - * Todo: 悩んでる所 - - - * fix: kernel/ppe/HTask.cpp - 今まで、manager->create_task で生成したタスクは - - - dependency の設定 - manager->set_task_depend(master, slave) // slave は master を待つ - - - 実行キューへの追加 - manager->spawn_task(master); - manager->spawn_task(slave); - - と、manager を介してやっていました。 - まあそれでもいいんだけど、特に dependency の所は - どっちがどっちを待つのかってのは、API見るだけじゃわからない。 - そこで、Task (HTask のこと) に、上二つに対応するような - - void set_depend(HTaskPtr) と void spawn(void) を追加しました。 - - - Usage - slave->set_depend(master); // slave は master を待つ - slave->spawn(); // slave をキューへ追加 - - 結局は、それぞれの関数の中では、上の set_task_depend とかを - 呼んでるんだけど、ユーザ側からするとこの方がわかりやすいと思います。 - -2008-02-16 Wataru MIYAGUNI <gongo@cr.ie.u-ryukyu.ac.jp> - - * tag: beta3 - ダブルバッファリングを追加し、まあなんとか動いてるんじゃない?って - ところまでですが、所詮 Fifo バージョンなので、 - そろそろ Cell を書き上げて、並列にちゃんと動いてるか確かめないとね - - * add: kernel/ppe/DmaBuffer.cpp - ダブルバッファリング用に作ったんだけど、 - せっかくなので、DMA は、このオブジェクト(が持つ二つの領域)でしか - 行えないようにする。ってのでどうでしょう。って話を先生としました。 - 並列処理だし、ダブルバッファリングがデフォでいいでしょう。 - というか、したくなければ swap_buffer とかしなければおk。 - - -Usage - DmaBuffer *buffer = manager->allocate(sizeof(SceneGraphPack)); - - 今までと違い、create_task の in_addr と out_addr には - DmaBuffer をいれてください。ユーザが自分で malloc/new したやつは - エラーを出すようにしてる(seg faultだけどね!) - 汚いソースだが、実際に使ってる様子は Test/simple_render の - viewer.cpp で使ってます。sgp_buff と pp_buff ってやつね。 - - もうすこしユーザに優しいAPIを作りたい・・・ - -2008-02-11 Wataru MIYAGUNI <gongo@cr.ie.u-ryukyu.ac.jp> - - * add: Test/simple_render - chiaki の DataPack を使った Cube の表示プログラム。 - 簡単に DataPack を TaskManager の scheduler (SpeManager) に渡して - 処理してコピーして、を繰り返してるだけなんだけど - まあ動いてる気がするのでいいんじゃないでしょうか。 - - -2008-02-10 Wataru MIYAGUNI <gongo@cr.ie.u-ryukyu.ac.jp> - - * tag: beta1 - この状況だと、できることよりもできないことを書くべき?違うか。 - - - task (親) 中で task (子) を生成することはできない - 正確には「生成はできる」だけど、その 子task が - 親task に依存している別の task を無視して動くので - ちゃんとした結果にならないと。 - 8日の Todo にも書いてあるけど、今の実装では - task が task を生成することを想定してない感じなので。 - 完全に spe 用にのみ狙いを絞った実装であって - OS って言えない実装であるからして、書き直すの? - 全ての関数を task しようとするとこうなる訳で、 - ある部分だけやるってのはまあできるんだろうけど、うーん。 - - - chiaki の simple_render が動かない - (追記) 解決しました - 単に read/write buffer のサイズが足りないだけだった。アホスwww - まあ辱めの為の下は残しておこう - - まだ cvs に commit してないけど、chiaki が書いた、 - DataPack 対応の simple_render に TasKManager を組み込んでみた。 - といっても、OSっぽく書いたんじゃなく、今は - update_sgp と create_pp だけを task 化してみた。 - でまあ動いてるような気はするけど、ものすっごい malloc 系の warning が。 - 時々長く動くよねみたいな感じになってしまっている。 - TaskManager が悪いのか、simple_render が悪いのか。 - この TaskManager、ある部分での malloc 系の問題に敏感だなあ。 - まあそうでなかったらバグの探しようも無いし、良いっちゃー良いんだが。 - - -2008-02-08 Wataru MIYAGUNI <gongo@cr.ie.u-ryukyu.ac.jp> - - * add: kernel/ppe/SymTable.cpp - 今まで func[] = {add, sum, ...} - とかやってかっこわるい言われまくってたので - 話し合いの通り Symbol Table みたいなものを作ることに - - // 疑似コードね - struct sym_table { - char *sym; // シンボル - void *address; // シンボルが示すアドレス - } sym_table[] = {{"Sum", &Sum} , {"Draw", &draw}}; - - int fd = get_fd("Sum"); - void *addr = get_address(fd); - - table には "Sum" と "Draw" っていう二つのシンボルが登録されている。 - 例えば、ユーザ(カーネル?)が "Sum" ってシンボルにアクセスしたい場合、 - まずは get_fd で "Sum" に対する、file descripter を返す。 - ユーザは、その fd に従って get_address を取得することが出来る。 - TaskManager 的な使い方をするなら - - // 俺は今、Draw 関数を使うタスクを生成したい - int fd = manager->open("Draw"); - manager->create_task(fd, size, in, out, func); - manager->open では get_fd と同じ使い方です。 - - まだ改良の余地ありそうですが、今は動いてるってことで。 - - - - 補足 - なぜ file descripter と表すか - - OS の昨日として、 fopen とかと同じ使い方もできるじゃない! - - - * Todo: task が task を生成する際の処理 - 今まで、 task が行う作業は、演算のみを行うような - 単純な実装に決め打ちされているわけです。 - しかし、OS なんかだと、タスク中から別のタスクを生成するとか - ありありだと思われる。てか今のテストプログラムでなった。 - - Test/Sum にあるプログラムで使われるタスク - - - init2 // 貧相な名前ですまない - 演算する数値とかバッファの初期化 - - - sum1 - ある範囲の整数 (i から i+16 とか) の総和 - - - sum2 - sum1 で求められた、複数の範囲の総和を一つにまとめる - (ex. 複数の sum1 が 1->16, 17->32, 33->48 の総和を計算し、 - sum2 で 上の3つの総和を計算する - 要は 1->48 の総和を分割するっていうプログラムね - - - finish - sum2 で求まった値を表示 - - この Sum というプログラム、というか OS と言おう。SumOS ね。 - SumOS は最初に TaskManager (所謂 kernel) を起動し、 - init を起動する。init では、予め決められたタスクである - init2 と finish の二つのタスクを create して登録する。 - init2 と finish には依存関係がある (init2 が終わったら finish) - init2 の中で、sum1 と sum2 というタスクが作られる。 - sum1 と sum2 にも依存関係はある (sum1 が終わったら sum2) - - 今の実装だと、タスクが終了して初めて次のタスクへ行く。 - まあ当たり前なんだけど、例えばそのタスクの中で - 新たにタスクが作られた場合、そのタスクが終了するまでは - 実行されなくなってしまう。 - でまあ、今は、manager->create_task される度に - manager->run とかして、無理やり起動してる訳さ。 - 何が無理矢理かっていうと、scheduler の役目をしている - SpeManager (これも名前変えないと) を2度呼び出してる訳。 - つまり、タスク中でタスクを作る度に、SpeManager オブジェクトを - new してるわけさ。いいのか?いや、動いてるけどね? - - ちなみに、Cell version だと spe が勝手に取っていってくれるから - 大丈夫かなと思いつつ、もし spe を1つしか使わない設定だったら微妙。 - - 要するに、タスク中でタスクが作られる場合の処理を考えないとね。 - -2008-02-07 Wataru MIYAGUNI <gongo@cr.ie.u-ryukyu.ac.jp> - - * memo: プログラミングの姿勢 - scheduler とか、task の管理をする部分は - kernel programing のつもりで、 - example とか、task に割り当てる処理を決めたりする部分は - user programing のつもりで。 - - それぞれ違った視点で見る必要がある - - * memo: OS というもの - OS 起動の流れ - - - PC の電源を入れる - - BIOS が立ち上がる (OpenFirmWare, EFI, BIOS) - - 起動デバイスをチェック (優先度とか種類とか) - - 起動デバイスから Boot loader を起動 - + BIOS によって、認識できるファイルシステムが違う(だっけ?) - + ファイルシステムのどこに Boot Loader があるか知っている - + grub, grub2, lilo, kboot などがある - - Boot Loader が kernel を起動 - + ネットワークブートの場合、TCP/IP や - ネットワークデバイス(イーサとか?)のドライバを持ってる必要がある - - kernel は、最初に scheduler を起動する - - scheduler の初期化 (init を呼ぶ?) - - init では、事前?に設定されているスクリプトとかを呼ぶ - + linux とかだと /etc/rc にあるやつを init が呼ぶ - - login form が起動 - - 補足 こっからユーザ - - login する - - shell を呼ぶ - + login shell かどうか確かめる - - ユーザに設定されてる起動スクリプト?を実行 - - 晴れてログイン - -2008-02-06 Wataru MIYAGUNI <gongo@cr.ie.u-ryukyu.ac.jp> - - * kernel/spe/*.cpp: new と placement new - 現在、spe kernel のタスクは、切り替わる毎に - new/delete を繰り返しています。今はこれでいいんだけど、 - 速度的にも、いずれは直さないといけないと思うわけで。 - で、予め allocate された領域を利用した placement new を使えば - new よりもそれなりに早くなるっぽい。 - 例題として、与えられた回数分 new/delete を繰り返すプログラムと、 - 同じ回数分、placement new したときの速度の比較 - - for (int i = 0; i < num; i++) { - - < task = new Task; - < task->init(i); - < task->printID(); - < delete task; - --- - > task = new(buff) Task; // buff = malloc(BUFF_SIZE); - > task->init(id); - > task->printID(id); - } - - placement new では、delete の必要は無い。 - その中で新たに allocate してるなら必要かもしれないが。 - 速度比較は以下。no_new が placement new で、ln_new が new/delete 。 - - % ./a.out 10 // 10 回 - no_new: time: 0.012135(msec) - ln_new: time: 0.003572(msec) - - % ./a.out 100 - no_new: time: 0.022453(msec) - ln_new: time: 0.018989(msec) - - % ./a.out 1000 - no_new: time: 0.115277(msec) - ln_new: time: 0.136335(msec) - - % ./a.out 10000 - no_new: time: 1.056156(msec) - ln_new: time: 1.322709(msec) - - % ./a.out 100000 - no_new: time: 10.622221(msec) - ln_new: time: 13.362414(msec) - - % ./a.out 1000000 - no_new: time: 109.436496(msec) - ln_new: time: 136.956872(msec) - - 10、100 回だと負けてるが、まあ無視しよう(ぇ - 回数が多くなるにつれて、ほんの少しだが no_new が勝ってる。 - どうなんだろうね。ちなみに printID を無くすと - - % ./a.out 1000000 - no_new: time: 0.008512(msec) - ln_new: time: 27.100296(msec) - - I/O に左右され過ぎ。まあそんなもんだろうけどさ。