はりぼて日記
2007 | 01 | 02 | 03 | 04 | 05 | 07 | 08 | 10
2006 | 11 | 12
1月 06 (土曜日) 2007
19:06
13日目3
 
13日目 [6] 終了〜。



・・・ちょっとあやしいってばあやしいけど、とりあえず芋づる式の概念を理解した上で読むと、なんとなく意味が解ってきたのでこれまで〜。
 
name: @Guest  Comment:
16:42
ちょっと脱線(芋ずる式を理解しよう)
 
まず、解るところまで戻ろう。P240のintandler20。





for (i = 0; i < MAX_TIMER; i++) {

if (timerctl.timer[i].flags == TIMER_FLAGS_USING) {

timerctl.timer[i].timeout--;

if (timerctl.timer[i].timeout == 0) {

timerctl.timer[i].flags = TIMER_FLAGS_ALLOC;

fifo8_put(timerctl.timer[i].fifo, timerctl.timer[i].data);

}

}





ええと。これはfor文を読めば解る。タイマー内のtimeout変数をひとつ減らす(つまり引き算)。これを500回繰り返す。(ただしTIMER_FLAGS_USINGを見て、使用中のもののみ。)

で、242Pに書いてある通り、この引き算はメモリから読んで引き算して再びメモリに戻すという動作なので、メモリへのアクセスが二回発生するので遅いと。なるほどなるほど・・・



で、P243の改良版がこれね。



for (i = 0; i < MAX_TIMER; i++) {

if (timerctl.timer[i].flags == TIMER_FLAGS_USING) {

if (timerctl.timer[i].timeout <= timerctl.count) {

timerctl.timer[i].flags = TIMER_FLAGS_ALLOC;

fifo8_put(timerctl.timer[i].fifo, timerctl.timer[i].data);

}

}

}





ふむふむ。timer.cを合わせて改良と・・・

なるほど。つまり、いままでは、count変数が初期化されてからの経過時間を(タイマーが初期化されてから150秒だよ!)記憶していて、timemout変数はタイムアウトまでの時間(10秒後にタイムアウトだよ!)を記憶していた。しかし、この意味を変更してタイムアウト変数は予定時刻を設定するわけか(160秒になったらタイムアウト!)。

これだと、メモリからtimeout変数を読み込み、count変数と比較するだけ(引き算した値をもう一度メモリに書かなくてもいい)なので、メモリアクセスが一回減るわけか。



で、P245〜P256の改良版。

・・・うーむ。なるほどぉ!。timerctl.next変数には、「次は11時45分がタイムアウトだよ!」というのを記憶しておくのかぁ。で、新しいタイマーが生成されるときにもそれを見て、もし新しいタイマー5番が11時30分タイムアウトだったら、timerctl.nextを11:30分に書き換えると。さらに新しいタイマー9番が11時28分だったら同じく書き換える。(そうするともう5番は見なくなる。9番がタイムアウトした後にどのタイマーが最新かな?ってもう一度見直して、一番近い時刻のタイマーのタイムアウト時刻を探し出し、timectl.nextに設定しなおすと。



で、最後。P246〜P248の改良番。





/* ちょうどi個のタイマがタイムアウトした。残りをずらす。 */

timerctl.using -= i;

for (j = 0; j < timerctl.using; j++) {

timerctl.timers[j] = timerctl.timers[i + j];

}

if (timerctl.using > 0) {

timerctl.next = timerctl.timers[0]->timeout;

} else {

timerctl.next = 0xffffffff;

}

return;





そっか。タイマーは最大で500個だけど、動作が3個とか10個とかの場合も500回タイマーのチェックをしていてはバカバカしいので、usingという変数を設けて、ここに「今は何個動いているか?」を記憶しておき、その数だけチェックをさせる。そしてタイムアウトが発生したら(どれか一個でも)その時点で再び「動いているor動いていた」タイマーを再チェック。残りのタイマーの位置(アドレス)を一個づつずらしておくと。



で、13日目の[5]。例のおかしな図がある「芋づる式」と。

・・・ん?あれれ?? ちょっとまって?。もしかしてこういうこと????



今までのずらし



 ┌──────┐            ┌──────┐

 │タイマー3番 │            │タイマー12番│↑

 ├──────┤            ├──────┤

 │タイマー12番│ 3番がタイムアウト!  │タイマー9番 │↑

 ├──────┤     =>      ├──────┤

 │タイマー9番 │            │タイマー32番│↑

 ├──────┤            ├──────┤

 │タイマー32番│            │タイマー16番│↑

 ├──────┤            ├──────┤

    :                    :

 ├──────┤            ├──────┤

 │タイマー18番│            │タイマー7番 │↑

 ├──────┤            ├──────┤

 │タイマー7番 │                    ↑

 └──────┘            



こんな風に、一個づつずらしてた。(つまり、メモリをずらす数だけ書き換えていた。100個なら100回、300個なら300回メモリを書き換えなくてはならない)

これを、



 ┌─────────────┐          ┌─────────────┐

 │タイマー3番(俺の次は12番) │          │             │

 ├─────────────┤          ├─────────────┤

 │タイマー12番(俺の次は9番) │ 3番がタイムアウト!│タイマー12番(俺の次は9番) │

 ├─────────────┤    =>     ├─────────────┤

 │タイマー9番(俺の次は32番) │          │タイマー9番(俺の次は32番) │

 ├─────────────┤          ├─────────────┤

 │タイマー32番(俺の次は16番)│          │タイマー32番(俺の次は16番)│

 ├─────────────┤          ├─────────────┤

     :                  :

 ├─────────────┤          ├─────────────┤

 │タイマー18番(俺の次は7番) │          │タイマー18番(俺の次は7番) │

 ├─────────────┤          ├─────────────┤

 │タイマー7番(俺は最後だぜ) │          │タイマー7番(俺は最後だぜ) │ 

 └─────────────┘          └─────────────┘  

   ●今は3番を監視 (s)                 ●今は12番を監視(s)   ←書き換える

●次はたしか12番(t)                 ●次はたしか9番 (t)   ←書き換える





と、こういう感じで、二箇所だけ書き換えればいい。次は何番というのは、タイマーを作成する時に一回だけやればいいと。(実際はいくつかパターンがあるので二箇所ってわけじゃないけど)



こういうことか? こういうことなのかあぁぁぁぁ!!!!!

(だいじょぶかな?これで。合ってるかな??)

 
name: @Guest  Comment:
16:37
13日目2
 
13日目 [5]



・・・だっめだ。「芋ずる式」がどうしても理解できない。

ちょっと中断。このタイマーの部分だけをもう一度追いかけて、一旦整理&理解に努めよう。(なんか二巡目に回してはいけないことのような気がしてきたので・・・
 
name: @Guest  Comment:
14:49
13日目
 
13日目 [1]〜[4] 終了〜。



ここらへんはさらに各所のチューニングですなぁ。



ん? バッファを一個にまとめる?? 

なんでそんなことするんだろう?。



あ〜ん。なるほどね。「見に行く回数が減る」と。

この理屈は解るけど、その分判定(ifやelse)が増えているような気がするなぁ。また、32bitになるってことは、余分にメモリを消費するという理屈にもならないだろうか???

(結果としてはちゃんと早くなっているのだからOKのはずだが、素朴に疑問に思った。どうなんだろう?これは後で種明かしとかが出てくるのかな?それとも「こういう処理よりこういう処理のほうが早いことが多い」みたいな、Kタンのノウハウかな??)

 
name: @Guest  Comment:
13:37
12日目
 
12日目 終了〜。



・・・うっわ。こまったなぁ。細かい部分を完全に理解しているかどうかってのはあやしいんだけど、なんかツルっと読めちゃった・・・



だって、ほとんどの処理がいままで作った関数とかの流用&カスタムなんだもん。「理屈の理解」程度では十分わかっちゃうわけで。



PS:

ここで、「もしタイマーを初期化しないでおくと497日でOSが破綻する」ということが書いてあった。497日? なんか、この数字、聞いたことがあるような・・・



あ!

これか!?
 
name: @Guest  Comment:
10:31
11日目2
 
11日目 [3]〜[8] 終了〜



・・・なるほど!mapか!



うーん。10日目の段階で、私も頭の中でウインドゥやマウスの無駄のない高速な書き換えを妄想してたんだけど(フローチャートレベルではあるが)こういう考え方があるのかぁ!



(ところで、つい、メニューバーをつまんでドラッグしてしまった・・・(^^; だってあんまりりっぱなウインドゥだったんだもん・・・)
 
name: @Guest  Comment:
10:02
11日目
 
11日目 [1]〜[3] 終了〜。



まあここはツルツル〜っと読んでと・・・
 
name: @Guest  Comment:
09:55
10日目3
 
10日目 [3]〜[4] 終了〜。



ここを読んでふと思った。この本の著者KタンはOSASKで有名な人。

で、OSASKはといえば、「もっと効率、もっとコンパクトに!」を身上とするOSとして有名。

しかしこのセクションでは、Kタンは猛烈に失敗を繰り返している。(まあ学習のためにわざとなんだろうけど)

やっぱりプログラムは、こういうふうに「まずやってみて、それから工夫をする」というスタンスが大切なんだろうなと改めて感じた。

(そもそも、稚拙でもベタでも、まずは全下じきを毎回書き換えるということをやってみて、見てみないことには遅いだのチラつくだのはわからないわけで)

(極論だが、最低級のPCでもこの方法でまったくチラツキ等がなければ、この工夫はいらないわけで)



(昔あった、ある失敗プロジェクトを思い出す。100m走に例えると、誰一人走っていないのに、「スタートラインはあそこがいい」「いやこっちのほうがいい。なぜなら・・・」とかそんなことにばっかり心を裂いていた。誰かが一人、「とにかく一度走ってみるよ」いうととたんにその行為を批判し始める。こんなんだったから、見事に失敗したんだろうなぁ・・・)
 
name: @Guest  Comment:
(1) 

PopnupBlog V3 Denali created by Bluemoon inc.