よもぎのメモ帳

備忘録的な感じで技術的なことをストックしていきます。

よもぎのOS自作入門 13日目/30日

はじめに

これは2020年夏休み企画「30日でOS自作してみよう!」13日目の記事です。

企画についてはこちら

y0m0g1.hatenablog.com

昨日やったことを書いていきます。 徐々に遅れてきていてぴえんになっている……*1*2

昨日の進捗

f:id:y0m0g1:20200831022021p:plain
32bir FIFOバッファを導入した結果

f:id:y0m0g1:20200831021355p:plain
番兵あり単方向線形リストによるタイマ管理

32ビットのFIFOバッファを導入して高速化を達成。タイマ管理を線形リストでおこなって更には番兵を導入しました。

昨日やったこと

まず、文字列を表示する関数の整理を行いました。

文字列の表示を更新する際には、まず背景色で塗りつぶしてその上から文字列を書き込み、レイヤーを更新=画面表示を更新するといった感じになっています。*3 これを一つの関数にまとめたものを導入しました。

次に行ったことは、FIFOバッファにpushするデータを変化させることで、タイマごとに作成していたFIFOバッファを1つにしました。 まあ、これも整理したみたいな感じです。

性能測定ということもやりました。前回はタイマ割り込みを高速化しましたが、どれだけ高速化したのか、タイマ割り込みを含む無限for文を回して計測します。 値が大きければ大きいほど高速です。本では、エミュレータだと値が大きくブレるため、実機を用意して5回計測して平均値で比べて、速くなったね!って結論にしてました。

私は実機を用意できなかったので、エミュレータでぶん回します。

No.1,2,3,4の4つは本の著者が配布しているファイルをそのまま利用したもので、4'だけは私が書いたコードを動かしたものです。 4と4'の内容はほぼ同じですが、記法に差があったり*4ヘッダファイルの記載順序に差があったり文字フォントがちょっと違ったりぐらいです。

No. 1 2 3 4 5 Ave.
1 94,086,157 91,699,360 99,730,486 96,469,851 102,707,128 96,938,596
2 88,355,085 99,134,242 94,067,772 101,741,159 95,596,553 95,778,962
3 96,383,465 101,601,101 101,919,894 100,596,892 104,772,383 101,054,747
4 88,339,210 83,316,140 103,526,678 105,139,205 105,404,150 97,145,077
4' 105,871,246 99,168,566 105,195,277 92,406,415 100,497,902 100,627,881

本来ならば1,2,3,4(4')の順で早くなるはずなんですが……数字ブレッブレだし有意差なさそう。 本では

それぞれの改良のたびに、少しずつ速くなっているのがよく分かります。

ってあるけれども、エミュレータ環境じゃわからなかった。

このあと、キーボード・マウス・タイマ割り込みのデータを保持するFIFOバッファを統合してみます。 無限for文は、今までこの3つのFIFOバッファを周回し監視していましたが、それが1つのFIFOバッファで済むようになります。 これを用いて性能測定した結果がNO.5'です。一応私が書いたコードを動かしているのでダッシュつけました。

No. 1 2 3 4 5 Ave.
5' 185,191,545 185,762,562 191,357,213 191,218,136 183,812,601 187,468,411

え、ちゃんと速くなってるじゃん。

このあとタイマに関する”改良”を行います。 タイマを複数保持する際に、今まで配列で行っていたものを線形リスト*5を用いて管理します。 つまり、”次の”タイマの構造体TIMERのアドレスを構造体に持たせるということです。

struct TIMER 
{
    struct TIMER *next; // 次のTIMER構造体のアドレス
    unsigned int timeout, flags;
    struct FIFO32 *fifo;
    unsigned char data;
}

こうすることで、TIMER構造体の追加や削除の操作をこのnextの値をいじることで済ませられるようになります。

また、番兵*6という存在を追加することで、プログラムを簡略化します。 ここで番兵は「絶対に最後のタイマとなって存在し続けるタイマ」となっています。この番兵はtimeoutが最大の0xffff_ffffで、nextが0*7となっています。 この存在で、タイマは常に1つ以上存在するということになって、状態管理も楽になります。*8

線形リストを用いたNo.6'の性能評価と、番兵を用いたNo.7'の性能評価は次のとおりです。

No. 1 2 3 4 5 Ave.
6' 173,318,586 188,405,102 191,047,069 178,178,628 185,483,631 183,286,603
7' 153,003,118 186,917,665 190,313,816 171,509,287 191,502,531 178,649,283

ちょっと遅くなった。これについては後日明かされる予定だそうです。

今日も一日頑張るぞい!

*1:何故か同期は倍速で進んでる

*2:進む君と止まった僕の縮まらない距離を--天ノ弱より

*3:本ではシートを更新するとかいう表現ですが、レイヤーのほうがわかりやすい

*4: if(condition){\n派かif(condtion)\n{\n派か

*5:今回は単方向線形リスト

*6:英語でsentinel

*7:最後なので次が存在しない

*8:タイマが存在しないということもなく、タイマを"次が存在しない"(=nextがない)最後尾に追加することもない