先日の日曜日、第十回 カーネル/VM探検隊&懇親会 (#kernelvm) に参加してきました。
相変わらず、カーネルVMは濃かった。僕の低レイヤー欲が非常に満たされる感じでした。
何故か、PDP-11 が熱かったです。勿論、美しいアーキテクチャですが、かと言って今の時代に PDP-11 というのも変な話ですが。
その前の週に LinuxCon Japan 2014 も学生無料枠 (first50) 参加したのでで、非常に濃い1週間でしたね。各所で話題になっていた、"ワタシハリナックスチョットデキル" Tシャツも頂きました、大切に使います。
ところで、僕はどんな LT をしたかというと、卒論ネタに少し絡めて発表しました。
卒論は主に SSDAlloc という、ハイブリッドメモリアーキテクチャ?を元に mist32 プロセッサの MMU を改造してフラッシュメモリをメモリの一部のように利用できる MMU を提案してみる、みたいな研究でした。
そこで、mist32 プロセッサ向けに OS を何か移植する必要があって、更に何かアプリケーションも動かす必要があったので、その時の話をちょっと。
具体的には、xv6 という UNIX V6 を参考に作られた x86 向けの MIT で使われている教育用 OS を、mist32 に移植して、更にその上で mruby を走らせられるようにポートしました。
xv6 移植については少し wiki の方にまとめました。
http://open-arch.org/software/porting_xv6
スライドは以下に乗せておきます。
もっと詳しく書きたいのですが、時間もないので聞きたいことがあったら気軽に @hktechno に聞いてください。
# しかし、自作プロセッサを作って OS を移植した程度では、#kernelvm 的には何の驚きも提供出来ないことがわかったので、さらなる高みを目指す必要がある。
2014/05/27
2013/07/22
glibc の関数の引数の数について調べてみた
Open Design Computer Project で作っている mist32 プロセッサの、関数呼び出し規則と割り込みについて考えてる間に、あるひとつの疑問が...
平均と言うよりは、最大でどれぐらいまでの引数が使われることが普通なのか。
何故こんなデータが欲しいかというと、関数呼び出し規則 (Calling conventions) でレジスタに引数を乗せることは確定だが、どの程度引数レジスタを用意すればいいのか、という事を決めたい。
関数呼び出し規則では、レジスタに呼び出し元か呼び出し先か、どちらで保存するかを定義しなければならない。基本的には、呼び出し先保存 (caller-saved) なレジスタの方が、効率が良いのである。実際に使われたレジスタしか退避することがないから。
全部引数に載せればいいじゃん?って思うかもしれないけど、レジスタが許す限り全部引数をレジスタに乗せることに決めた場合、すべてのレジスタが呼び出し元保存 (callee saved) なレジスタになるので、問題が起きる。呼び出した先の関数がどのレジスタを使ってるのかなどわからないので、呼び出し元の関数で使ってる変数レジスタをすべて退避する必要がある。その先の関数でそれを使っていないかもしれないのに。また、割り込みの際にも、呼び出し元保存のレジスタは、基本的に割り込みハンドラで保存しなければいけないし、多すぎるといいことはない。
つまり、どの程度の数の引数が一般的に使われるかがわかれば、ほとんどの数の引数をレジスタ渡しで実現しつつ、無駄なレジスタ退避を少なくすることができる、理想の引数レジスタの個数をなんとなく予測することができる。
ふつうの関数は、どれぐらいの引数を使うのか
平均と言うよりは、最大でどれぐらいまでの引数が使われることが普通なのか。
何故こんなデータが欲しいかというと、関数呼び出し規則 (Calling conventions) でレジスタに引数を乗せることは確定だが、どの程度引数レジスタを用意すればいいのか、という事を決めたい。
関数呼び出し規則では、レジスタに呼び出し元か呼び出し先か、どちらで保存するかを定義しなければならない。基本的には、呼び出し先保存 (caller-saved) なレジスタの方が、効率が良いのである。実際に使われたレジスタしか退避することがないから。
全部引数に載せればいいじゃん?って思うかもしれないけど、レジスタが許す限り全部引数をレジスタに乗せることに決めた場合、すべてのレジスタが呼び出し元保存 (callee saved) なレジスタになるので、問題が起きる。呼び出した先の関数がどのレジスタを使ってるのかなどわからないので、呼び出し元の関数で使ってる変数レジスタをすべて退避する必要がある。その先の関数でそれを使っていないかもしれないのに。また、割り込みの際にも、呼び出し元保存のレジスタは、基本的に割り込みハンドラで保存しなければいけないし、多すぎるといいことはない。
つまり、どの程度の数の引数が一般的に使われるかがわかれば、ほとんどの数の引数をレジスタ渡しで実現しつつ、無駄なレジスタ退避を少なくすることができる、理想の引数レジスタの個数をなんとなく予測することができる。
2013/07/18
エンディアン変換とバイトアクセス
最近、Open Design Computer Project で mist32 プロセッサのシミュレーターを作っています。I/O のエミュレーションにもある程度対応してます。
https://github.com/techno/mist32-simulator
そこで気づいたことをひとつ書こうかなと。あたりまえのことなのですが。
上記が、ビッグエンディアンとリトルエンディアンの概要です。ビッグエンディアンの方が人間には自然に見えますが、コンピューター的にはそうでない面もあり、一長一短です。一般的に使われている x86 はリトルエンディアンを使っています。
ファイルシステムや、ネットワークプロトコルなどによって、エンディアンは普通は規定されています。(FAT はリトルエンディアン、ネットワークはビッグエンディアン) しかしながら、ELF のようなメモリイメージのようなフォーマットは、そう簡単に行きません。
https://github.com/techno/mist32-simulator
そこで気づいたことをひとつ書こうかなと。あたりまえのことなのですが。
ビッグエンディアンとリトルエンディアン
ご存知の通り、この世のコンピューターは内部的にエンディアンやバイトオーダーと言われるような、1ワードのバイト列をどのようにメモリ上に配置するか、という手法が大きく分けると2つあります。Data: 0x1234ABCD 0 1 2 3 Big Endian: 12 34 AB CD Little Endian: CD AB 34 12
上記が、ビッグエンディアンとリトルエンディアンの概要です。ビッグエンディアンの方が人間には自然に見えますが、コンピューター的にはそうでない面もあり、一長一短です。一般的に使われている x86 はリトルエンディアンを使っています。
ファイルシステムや、ネットワークプロトコルなどによって、エンディアンは普通は規定されています。(FAT はリトルエンディアン、ネットワークはビッグエンディアン) しかしながら、ELF のようなメモリイメージのようなフォーマットは、そう簡単に行きません。
登録:
投稿 (Atom)