091118

|


ちょっと秋葉で買物してきました。液晶工房でデバッグ用とかの予備にLCDモ
ジュールを二つほどと、秋月で3軸加速度センサ、なんとなく棚を見ていたら、
測距モジュールというのがあって、興味をひかれたので買ってきた。フレーム
側にこれをつけて、スイングアームに反射板をつければストロークをとれない
だろうか...。と思って。400円だし。



なんでLISPのスタックは1960年代からこんな七面倒臭いことをしてるんだ。そ してなんでいつまでたっても(現在でも)浅い束縛、深い束縛とかやってるんだ。 とググっていたら今日は終了。
そもそも一番のミスリーディングがLISPが最初から動的スコープで設計された ことのようだ。だからリソースの限られた時代から、その関数が評価される時 に最後に値が束縛された場所を探すということをしないといけなくなった。そ こでその実装に浅い束縛と深い束縛の二つのやり方ができた。Emacs lispは動 的スコープで浅い束縛のようだ。しばらくして静的スコープのSchemeができた。 静的スコープならシンボルの値を実行時に探しにいく必要はない(よね?)
ALGOL系でもdisplay方式というのがこれと同じようなことをしていたようだ。
あまり深入りしない方がよさそうだな。しかし、これは...と思いつつ、構造と してはなんとなく魅力を感じてしまうところがLISPの息の長さか。いわゆるコ ンピュータ詐欺の条件を満たしている。マイクロカーネルとか^^、Ne
ググっている最中にちょっと面白いのをみつけた。「Continuation base Cコン パイラのGCC-4.2による実装」与儀健人 河野真治 2008? これは今回マイOSに導 入したUsing Continuations to Implement Thread Management and Communication in Operating Systems. Richard P. Draves Brian N.Bershad Richard F.Rashid Randall W.Dean Oct 1991 のような事を言語レベルに落とし ている。OSへの適用も示唆しているけれど、OSだとこれが適用する部分に専用 の言語を入れるくらいならCとアセンブラでサブルーチン形式に実装した方がい いのでは? でもこれの提案には非常に共感する。そんなところを考えていた。
継続をもっと使ってみたいというのは思ってるんだよね。ファイバの改装計画 はそこを考えている。しかしそこで専用スタックはもたないようにするという 条件にしてるので(今はもっている)局所記憶はあらかじめ用意されたとこにとっ ておくことになる。となると、コンテキストを指定したfunc(context)とそう変 わらなくなってしまう。それでもまだそうしようとする理由には、Cのリターン ではなく継続を呼ぶことでtry catchのような末尾呼び出しができる。といって もそれは多少コードの量が減る程度。ファイバにスタックとして局所記憶を持 たせれるならば、かなり複雑な状況(スタックを使った)で継続を渡すことがで きるのに、制御を渡した時にスタックを放棄するとなると、それって関数呼び 出しと変わらないよね。ということになってしまう。
ここでなんでスレッドに継続を適用してよかったかというと、それは
  • ブロックしてる間に他のスレッドにスタックを開け渡せるから空間的が節約できる。
  • 継続でブロックしているスレッドはその制御領域を見て、その継続がどこで あるかがわかる。だとすれば、データの受け渡しの場合、供給側がブロックす る時に、今ブロックしているスレッドの中から消費側を見つけることができて、 その場合、スタックを介してデータを渡せる。(マイOSでは未実装)
  • 明示的に末尾呼び出しの最適化ができる。
  • 状態遷移が書きやすい。
ファイバに実装するとなると、スレッドとの違いはそこにスケジューリングが あるかないかだけだ。なんでスケジューリングがあるかというと、スレッドで はもうやる事がないから、他のスレッドの結果を待つためだ。ここはファイバ では、やる事が終わったら次に渡し、やる事がなければ親に戻るということに なる。コンテキストスイッチが必要でないということは、関数呼び出しでもい い。スレッドの場合、呼び出すことは可能ではない。必要な供給者スレッドの 継続を呼ぶこともできるかもしれない(この操作は割込み形態になると思う)、 それも割込み待ちなら、何をすればいいということになる。マイOSの場合、何 もすることがなければ、スケジューラでスピンして割り込みを待つ。その割り 込みがどこかのスレッドを起こすので、そこから制御がはじまる。
ファイバが専用のスタックを持たないなら、ファイバ間をthread_blockとする ことも可能だ(これはこのファイバの親のスレッドがスタックを放棄できる時だ け)。これはきめ細かいけれど、時によってオーバヘッドの大きいスケジューリ ングになる。ファイバの先でブロックするのにその継続先は親のスレッドの先 頭だ。もし、スイッチせずに同じスレッドに戻ってくるなら、かなりの無駄骨。 そのままファイバで継続すればいい。
この部分を全部Cの関数で実装したとしたら、これは全部ファイバの継続でやる ことと同じになる。もしthread_blockをして何かの性能があがるなら、やる価 値はあるか...。
そして、ファイバの継続とした場合、そのデータの受渡しの手順をどうするの か。今は呑気にグローバル変数を介している。