[Subject Prev][Subject Next][Thread Prev][Thread Next][Subject Index][Thread Index]

[OSASK 590] Re: knimu1.



  こんにちは、川合です。


橋 さんは 2000/05/06 00:56:21 の「[OSASK 588] Re: knimu1.」で書
きました:

>うーぐー、指名されてしまった。

  だって、リリースしてから半日以内で確実にダウンロードしてくれる
んだもん。今や、テスターとしては鏡のような存在です。

>でわ全部ではないけど、こんなところかな?
>・knimu0では、(800*600モードで)マウスカーソルが境界線で
> 止まるようになってたけど、枠外でも描画が行われていた。これが
> 枠外の描画が行われないようになっている。
>・カウンタの速度がめちゃくちゃ上昇。カンスト狙いのあなたもこれでOK(笑)
>・カウンタがループすることを確認。1と2&3とは微妙にタイミングがずれている?
> (2:1:1ではあるんだろうけど、スタートタイミングが微妙にずれてる?)
> ループはそれぞれ個別に行われていることを確認。

  さて、これらの点も含めて説明しましょう。

  最初はマウスの話題です。

  knimu0までは、マウス表示のアルゴリズムはこんなものでした。

・実際の表示解像度とは無関係に832x630というVRAM構成にする(だか
  ら、表示が640x480でも、VRAM上は832x630になっていた)。

・こうすれば、16x16のマウスカーソルがVRAMの外に出ることはありえ
  ないので、クリッピング処理をすべて省略してマウスカーソルの表示
  /非表示を制御した。

  knimu1へ移行するにあたって、僕はより速いマウス表示/非表示アル
ゴリズムを見出したので、それを試したくなりました。それは、16x16
ドット分のVRAMを別途必要としていて、これからもそのアルゴリズムを
他の用途に使っていくかもしれないことを考えると、VRAMは貴重な資源
のように思えてきました。・・・そうすると、クリッピング処理の省略
のために仮想VRAMのサイズを広げるのはナンセンスであるような気がし
てきたので、仮想VRAMのサイズを小さくしてクリッピング処理をするこ
とにしました。

  結局、knimu1でのマウス表示のアルゴリズムはこんなものです。

・実際の表示解像度とは無関係に800x600というVRAM構成にする(だか
  ら、表示が640x480でも、VRAM上は800x600になる・・・ここも640x4
  80で処理した方がVRAMの未使用領域が増えるんだけど、処理は複雑
  になる。640x480は主流にならないと思っているのであまり考慮して
  いない)。

・マウスカーソルのクリッピングをちゃんとやり、指定された枠からは
  み出さないようにする(デバッグのときのなごりで今はその枠が640x
  480になっている。そのう、この枠は800x600に拡張されるので、knim
  u0との表示上の違いはなくなる)。

  ・・・ということで、マウスカーソルの表示アルゴリズムが変更され
た、というのが第1の変更点です。

  マウス関係の変更点はもう一つあります。・・・それは、「厳密な重
ねあわせ処理をするようになった」です。これが第2の変更点です。

  knimu0でマウスカーソルをカウンターに重ねると、カーソルはカウン
ターの下敷きにされてしまい、マウスカーソルは壊れてしまいます。こ
れは文字表示ルーチンがマウスカーソルとの重ねあわせ処理を全く考慮
していないせいで、マウスカーソルの処理としてはふさわしくありませ
ん。

  knimu1は、この辺の処理をちゃんとやっています。マウスカーソルと
の衝突判定を行ない、オーバーラップしたら重ねあわせ処理をしていま
す。ですから、カーソルがカウンターに「負ける」ことはなくなりまし
た。

  マウス関係はおしまいです。次はタスク制御関係。

  knimu1から、シグナル処理が部分的にサポートされました。OSASKに
おけるシグナル処理は、タスク外からの要因でタスクに割り込みをかけ
る機能です。

  この機能を使ってカウントスピードを上げています。これが第3の
変更点です。

  カウントが速くなったのを見て、「もしかしたら、カウンターは1ず
つ増えているのでなく、一度に3とかそれくらいの数が増えているんじ
ゃないか」と思う人がいるかもしれませんが、そんなことはありません
。ちゃんと1ずつ増えています。ずるはしていません。

  今回、カウントが劇的に速くなったのは、カウント値の画面表示タイ
ミングが変更されたためです。

  knimu0では、カウントを1増やすごとに、その値を画面に表示してい
ました。カウントを1増やす処理にくらべれば、画面に数字を書く処理
はめっぽう重く、結果的にカウントはゆっくりになりました。

  knimu1では、カウントを1増やすごとに画面表示することをやめまし
た。カウント部分は単純な無限ループを構成していてカウントしかして
いません。では、いつ表示するのかというと、こういう仕組みです。30
ミリ秒ごとにシグナルを受け取るように細工しました。タスクはシグナ
ルを受け取ると、そのときのカウント値を出力します。・・・と、それ
だけのことです。人間の目には、30ミリ秒以下の書き換えなんて多分分
からないだろうということでこの時間が選ばれています。

  今回の高速化の例は、タイマーシグナルを使えばプログラムを効率よ
く実行できるという一つの例でもあります。

  30ミリ秒の間に1000カウントが行われるなら、それはknimu0を少し改
造してカウントが1000の倍数のときだけに表示するようにすればいいの
ではないか、といわれるかもしれません。確かにそのとおりです。タイ
マーなど使わなくても、1000カウントに1度だけ画面に出力するプログ
ラムなら書けます。しかし、そのプログラムをマルチタスクで100タス
ク平行に走らせると、それぞれのカウンターが1000増加するには平均で
30ミリ秒x100 = 3秒もの時間がかかり断続的な書き換えをしているのが
明らかに分かります。タイマーシグナルなら、平行に走っているタスク
数がいくつであってもシグナルは30ミリ秒に1度です。その時は、カウ
ントの増える速度は当然落ちますが、全てのカウンターが十分に頻繁に
書き換えられ、書き換えを間引いていることは人間には分かりません。

  knimu0では、3つのカウンタは実は別々のタスクなんかではなくて、
完全に連動しているのではないか、と問われると少々回答に窮するほど
のシンクロをしていました。タスク実行時間比が高い精度で2:1:1だっ
たのです。knimu1もその比はそのままですが、タイマーシグナルの頻度
は3つのタスクで同じ30ミリ秒なので、微妙に比が狂うかもしれません
(でも多分普通の人じゃ分からない)。

  また、マウスカーソルと文字表示が重なると重ねあわせ処理を行ない
ますから、時間がかかります。そのため、タスク時間を余計に消耗する
ことになり、カウントが遅れます。たとえば、タスク2のカウンタの上
にマウスカーソルをおけば、タスク3との差が少しずつついていくこと
でしょう(すぐには分からないので、1分以上待ってみてください)。

  もちろん、knimu0と同じくらいの精度で見た目の実行時間比を保ちつ
つ、タイマーシグナルの利用とマウスカーソルの重ねあわせ処理の両方
をやることはできます(カウント用のスレッドと表示用のスレッドに分
けて、表示にかかる時間がカウントする時間と干渉しないようにすれば
いい)。しかし、今回はあえてそれぞれのタスクが別々であることを「
分かる」ようにしたかったのでやっていません。

  まあ、タスクの実行時間比の正確さに興味があるなら起動したときか
らマウスを動かさずにじっと見ていればいいですし、それぞれが本当に
別々のタスクなのかどうかが疑問になってきたら、マウスを動かして書
き換えの「じゃま」をしてみればいいでしょう。

>あと、knimuからだけど、マウスカーソルの動きがなんとなく
>気持ちいいような気がします。(気のせいかもしれんが)

  それは多分、気のせいです。OSASK ver.0.0とknimu0とでは、マウス
処理に差がありませんから。


  それでは。

--
    川合 秀実(KAWAI Hidemi)
川合堂社長 / OSASK計画総指揮 / カーネル開発班
E-mail:kawai !Atmark! imasy.or.jp
Homepage http://www.imasy.or.jp/~kawai/