業務報告

(進行度とか理解度とか得意不得意分野とかとにかくいろいろ知るために適当に話をしてみるかなあ。)
→『集積回路とかやってて、アセンブラでのサブルーチンコールとかも学校でやりました』
→(うっわオレなにもしなくてよさそー)



特に質問に答えるとかしてない時間を使って行った内容です。
1. まずディスプレイのサイズを取得するのと、背景シートのバッファに書き込むAPIを追加しました。ブリット操作(ピクセルデータをコピーすること)は最小限にしたかったけど、OS上のバッファポインタにアプリ上のバッファへのポインタを代入すると、アプリが終了したときにそのバッファが無効化(多分少しの間は耐えるだろうけど他のアプリがそこに割り当てられて使いだすと多分死ぬ)されるので、対処コードをどこかに書かなくてはならないので面倒くさいのでとりあえずOS空間のバッファにコピーすることにしました。そういやDirectXとかのグラフィクスAPIでよく聞くフリップってできるのかな。VRAMの開始アドレスを変更するってことなんだけど。まあ今はシートシステムがVRAMに書き込んでるんだけど。これの結果が後ろの同心円です。タイマで色が中心へ動きます。256色パレットの順番になってます。マルチタスクと重ね合わせシステムがしっかりできているので背景が動きながらウィンドウ操作や他アプリの動作が非同期で行えます。
2. 教科書には書かれていないが、Wikiに書かれていることを行うとFPUが使えるようになって、float/doubleが使えるようになるという話。FPUのレジスタはやけにサイズが大きく、FPUを使うタスクは多分そんなにないと考えられるので、タスクスイッチの度に通常のレジスタに加えてFPUのレジスタも保存していたら切り換えにかかるオーバーヘッドが残念になる。というわけでCPUもそれを分かっててそれ用の機能があるので利用する。タスクスイッチをするたびにコントロールレジスタのタスクスイッチビットが1になり、それが1の状態でFPU命令を実行すると0x07の割り込み(例外)がかかる。OSでは現在のFPUレジスタがどのタスクのものかと、各タスクのFPUレジスタの保存データをメモリにおく。割り込みを受けたらTaskRegisterから現在のタスク番号を得て、まあ後はうまくやればできるよね(TSビットは0にしよう)、と。まあ書いてあることをそのままやっただけ(爆笑)。その成果が左上のうにょうにょの3Dワイヤーフレームです。スーパーうにょうにょ1をダウンロードしてきてXFile(テキスト形式)を適当なCプログラムでCの配列コードに変換しました。タイマでXYZ軸で適当に回して、綺麗に見えるようにスケーリングと平行移動をかけました。他にも手やグラスのメタセコイアデータを拾ってきて変換し、スペースキーで変更できるようになってます。そういやライン描画APIで画面範囲外に書き込もうとするとバッファオーバーランする不具合を修正した気がします。
3. 右上はFPUが使えるようになったときに川合先生からリクエストがあったマンデルブロ集合のフラクタルです。上下左右移動と中心へズームイン・アウトができます。…それだけなんですが、なんだか非常に受けがよかったです。なお、エミュレータだと遅すぎてたまらないので1点当たりの上限ループ数をスペースキーで切り換えられるようになっています。


生徒の質問と回答の要約。

  • メモリの使用量をパーセント表示&メーター表示したい
    • A. using / total * 100 の順番を変えて using * 100 / total にすると全部整数演算のみでできます。ただし精度はパーセント表示の1の位までで、小数点以下は切り捨てになるけどまあいいでしょう。
    • Q. 実機ではトータルメモリが3GBとかで、使用メモリもそれに合わせてGBオーダにすると32bit unsigned intでusing * 100がオーバーフローしてぶっ壊れます。
    • A. 4GBが32bitの壁でちょうどその付近の話だなあ。とりあえずここは割り算をする前に割られる数と割る数をある同じ数で割ればいいと思います。(using / K) * 100 / (total / K)。どんな数でもいいんだからここは高速な右ビットシフトでの2の累乗での割り算を使ってみては?100をかけて耐えるようにするには128、つまり7ビットシフトすれば十分かな。一応totalが割り算で0になるとゼロ除算がアレだけど、トータルメモリが1KB未満て…。まあ…うーん…いいんじゃね?
    • Q. ビットシフトを使ってみましたがなんかすごい数のパーセントになりました!
    • A. このすごい数は左のほうのビットが1になってます。多分ビットシフトのときに左に1が詰められたんでしょう。ビットシフトに関係している変数をすべて調べて全部unsignedになっているか確認してください。(補足:signedの負の整数を右シフトしたときの動作はCの規格では不定だそうで)→経験(爆笑)があればそのやけに大きな変な値を見てから一本道で直せるよ(爆笑)。
  • %(剰余計算)のゴタゴタについて
    • Q. 負の数を%すると負の数になるんですか?
    • A. 数学的には -1 mod 3 = 2 だったりするんだけど、結果が定義されていなかったりされていても言語によって違ったりとかいいことが全くないのでどちらのオペランドにも正の数を使うのを強くおすすめします。また、signedの乱数を負の時単項-演算子で正の乱数にしようとするのは危険。8bit2の補数表現でいうと10000000(-128)は正負反転しても-128です。8bitだと1/256、32bitだと1/40億くらいの確率でバグります。-128〜+127を見ると分かるように、0を中心に対称というわけではないんですね。負の時128を足して-128〜-1を0〜+127にするとか、むしろAND演算で一番左の符号ビットを0にしてしまう(おすすめ?)のがいいと思います。
  • D班からの緊急要請:フラクタルが描きたいです
    • A. よく考えたら中学生だった。無茶苦茶言ってごめんなさい。しかし気合いで突破。うぇうぇうぇ。疲れたでござる。