Island Life

2005/11/01

う〜。0.8.6リリース寸前にもたついている。

どうもメモリ絡みのやばいバグが潜んでる模様。 び?さんのレポートするMacOS X最新版での不具合もひょっとすると同根かも。 これまでの経過。

  1. こっちでテストできるプラットフォームのほとんどでテストは通ってるのだけれど、 SolarisでのテストがAssertion failedで落ちることが発覚。
  2. dlopenされるモジュール中のScmIdentifierであるべきオブジェクトが 全然違うオブジェクトに化けているので、gc絡みだろう
  3. root setの登録ミスをまず疑うが、値をダンプしたりScm_GCSentinelを 使ったりして調べてみると、 「root setとして登録されているアドレス範囲から参照されているにも かかわらず、GCされている」ことが発覚。gcのバグを疑い、gc/ 以下に突入。
  4. mark_rts.c, mark.c, os_dep.c と読んで、「root setに登録されているが、 ページに一度もdirty bitが立ったことがないことになっているのでmarkされていない」 ことが発覚。dirty bitはOSから得ているのに、おかしいぞ? OSのバグの可能性は低い…
  5. 「一度でもdirty bitが立ったことがある」ページはGC_written_pagesで 管理されている。このビットマップは、一度 '1' になったら決して '0' になることは ない。ところが、問題のページに該当するビットを追っていると、最初はちゃんと '1' になっているのに途中から '0' になっていることが判明。あれれ。
  6. 念のためビットマップのバックアップをstaticに確保しといて 比較するプローブを組み込んだら、今度はテストが通る。→ちうことは、 GaucheのどっかのコードがGCのデータ領域に間違って書き込んでるっちゅうことじゃん!

さすがにこの爆弾を抱えたまま出すわけにいかないので、引続き調査中。

Tag: Gauche

2005/10/05

正規表現/\w/にマッチする文字の並びを得る方法

Rubyだと色々やり方があるみたい。Gaucheでは

(use srfi-14) (char-set->string #[\w])

Tags: Programming, Gauche

2005/10/04

AutodeskがAliasを買収

これでMayaでMELの代わりにLispが使えるようになることは…無いだろうなぁ。

Tag: CG

2005/10/04

毎年恒例(?)、Franz社の2日間にわたるLispセミナーが今年も開催されるそうです。

「2日間みっちり! Lispチュートリアル&Lispセミナー&Lisp事例紹介」

去年はAllegro Common Lisp 7.0の正規表現ライブラリについて 発表させてもらったんですが、今年は残念ながら行けません。 1日目のJansによる「Lispゲームプログラミング」が気になるなあ。

Tag: Lisp

2005/09/30

最上の日々 9/28より:

1、関数型プログラミングは、たまたま並列性を最大に記述する方法でもある。それを利用すれば並列性の抽出は容易だ。

2、関数型のプログラムの構文木を直接実行するプロセッサがあるといい。でもそこまで行かなくとも二股同時実行コール命令を追加するだけでも効果がある。

2.について。面倒なのは呼び出しより帰って来た後の同期だから、 「二股同時コール」はそこまで含めてのことだろう。 ただ、プロセッサレベルでは非同期呼び出し命令と同期命令に分かれてた 方が使いでがあるし、そうなるんじゃないかと思う。(言語レベルでの並列 呼び出しをコンパイラが非同期呼び出し+同期命令に展開すればいい)

例えばPS2ではコードとデータを用意してDMAをキックすることでVUが (CPUと並行して)計算を進めてくれる。結果を受け取るには 確かVUから割り込みもかけられたと思うが、コンソールゲームでは 計算時間の予測がたてやすい場合も多くて、CPU側である程度他の計算を 進めてからポーリングして同期していた。

ハードウェアでマルチコアに複数のスレッドを振ってくれるような機構が 出来たなら、非同期呼び出し命令も同期命令もスレッド操作のプリミティブ として処理されることになるかな。

1.について。副作用無しの関数型プログラミングは、 それだけでは並列性の記述には不十分だ。

「AかつB」「AまたはB」というパターンには、AとBを独立して評価できる場合と Bの評価可能性がAの評価結果に依存する場合がある。 後者の例は(and (char? x) (char=? x #?a))。 逐次プログラミングでは両者の区別は不要だが、並列プログラミングでは 区別してもらわないと、前者でAとBを並列に評価する機会を失う。

これはかなり本質的な違いで、「『AまたはB』でAかBの いずれかが停止しなくても、もう一方が停止すれば答えが出る」 というセマンティクスは並行演算を前提としないと実現できない。

これらの演算は実用的には非常に重要だ。並列演算を適用したい大きな データセットを扱う問題であっても、得たい答えは入力の データセットより遥かに小さい場合が多い。 ということは多くの問題で、どこかでたくさん並列に流れてた データの流れがぐっとしぼられる点が必ず一つ以上あるということだ。 例えば「たくさんのものの中から(どれでも良いから)ひとつ条件を満たすものを選ぶ」 という操作は頻出するけれど、関数的な素直な記述:

(define (find pred set)
  (cond ((pred (car set)) (car set))
        (else  (find pred (cdr set)))))

からは並列性は抽出できない。

並列に条件判断を走らせて、どれかひとつが帰って来た時点でそれを採用し 他は捨てる、ということになれば、走っている並列演算をキャンセルする機構も 組み込みで必要になる。

Tag: Programming

More entries ...