現代の量子力学

主に精進の様子を記録する日記帳です

9日目 メモリ管理

1. ソースの整理
    長くなったbootpack.c の一部をkeyboard.c とmouse.c に分割。
 
2. メモリ容量チェック (1)
    まずはメモリの容量をチェック。その前に、キャッシュを停止する必要がある。
2.1 キャッシュとは
    キャッシュとは、CPU内部にある小さいメモリ。メインメモリを読んだり書いたりすると、キャッシュメモリにアドレスとその内容を記録するようになっている。これによって、メインメモリの同じアドレスにアクセスする際にキャッシュメモリを参照することで高速にデータを取得できる。
    書き込む際も、とりあえずキャッシュメモリに書き込んでおいて、暇な時にそれをメインメモリに書きにいく。
    例えば、for(int i = 0; i < 100; ++i) {} の中では、i にはどんどん違う値が書き込まれていくわけだが、キャッシュ制御回路はこの様子を見て、メインメモリにi を書き込むのを一旦やめて置いて、キャッシュの中だけで処理するようにする。そして、i が100 になって落ち着いたらようやくメインメモリにi の情報を書き込む。
2.2 メモリチェック
    さて、メモリチェック。メモリチェックはメモリに適当な値を書いてみて、その直後にそこを読んでみて、書いた値と等しい値が入っているかどうかでチェックする。
    この時に、キャッシュが挟まると、メインのチェックしたいメモリにはアクセスさせてもらえずに書いた値と読んだ値が等しいという結果になるので、正しいチェックができない。ので、停止。
2.3 386?486?
    キャッシュ機能があるのは486以降のCPUなので、まずCPUが386か、486以降かをチェックして、486以降ならキャッシュを停止するようにする。
    CR0レジスタの中にあるフラグをいじることでキャッシュを停止させることができる。これにアクセスするにはアセンブラ
2.4 実際にメモリチェック
    チェックの手順は、あるアドレスにアクセスして値を覚えておく→そのアドレスに適当な値を書き込む→メモリ上でそれを反転させてみて反転したかどうかをチェック
    実際に0x00400000〜0xbfffffff をチェックしてみると… 3072MB!これはおかしい。←これにならなかった…
 
・キャッシュはCPU内の簡易的なメモリ。メモリチェックは実際に書き込んでみる。
 
3. メモリ容量チェック (2)
3.1 コンパイラの最適化
    C言語アセンブラを出力して見たい。gcc -S hoge.c でアセンブラが作られるけど、nasmで書かれてないのでさっぱり。
    どうやら2.4 の問題(手元の環境では起きてないのだが)はコンパイラが無駄な部分を最適化してくれていたのが悪かったらしい。
    ので、Cコンパイラを通さずにアセンブラでメモリチェック関数を実装。
 
コンパイラはかしこい
 
4. メモリ管理に挑戦
4.1 メモリ管理の必要性
    メモリはアプリケーションの起動に必要だったり、使い終わって不要になったりする。
    どれが今使用中でどれが空いているかを管理する必要がある。
    メモリ管理の基本は確保と解放。
4.2 実際にどうやるか
    一番簡単な方法は、どのメモリが使用中かの表を作成する。
    例えば、128MBのメモリを4KB単位で管理するとする。128 MB / 4KB = 32786 バイトの領域を作成して、そこに0か1を書き込んで、使用中かどうかをメモしておく。
    これだと表が大きすぎるのと書き込み読み込みに時間がかかるので、もう少し賢いやり方にする。
    xx番地からooバイトだけメモリが空いている、という情報を表にしておく(配列にして持っておく)方法
    これだと早いし、表も小さい。ただしプログラムがちょっと複雑。
    
    正しいのか?分かんね〜
・メモリの管理は大切