Hongli LaiによるMaking Ruby’s garbage collector copy-on-write friendly, part 7にあったパッチをベースにtrunkを変更してみた。
で、このパッチがなにをやっているか、という話。
Rubyが使っているGCは古典的なマーク・アンド・スイープGCで、 基本的アイディアは 「ルート」から再帰的に参照可能なオブジェクトに「生きている」マークを付け、 最終的にマークのついていないオブジェクトは「死んでいる」と見なして回収する、 というものだ。
この「生きているマーク」を付けるという作業がcopy-on-writeと相性が悪い。
最近のほとんどの(全部の?)OSはプロセスのコピー(要するにfork)を 行った場合、仮想記憶上ではメモリ空間をコピーしない。 同じ内容なんだからコピーするのは無駄でしかない。 とはいえ、プロセスの実行に従って、メモリは書き換えられるから 書き換えをOSが検出して書き換えが起きる直前にオンデマンドでそのページをコピーする ことでコピーを最小限にしようという発想だ。
それはいいのだが、これとRubyのGCが組み合わさると せっかくページ共有してコピーを抑制しようとしたのに、 「マークを付ける」ことによってすべてのオブジェクトが書き換わってしまう。 GCが発生した瞬間に結局Rubyのオブジェクトを含む全ページがコピーされてしまう。
そこで、このcopy-on-write friendly patchだ。
マーク・アンド・スイープGCにはオブジェクトごとの「生きているマーク」は必須だが、 そのマーク(フラグ)は必ずしもオブジェクトそのものに埋めこむ必要はない。 「生きているフラグ」を別の領域(ビットマップテーブル)で持ち、 マークによってオブジェクトを書き換えないというのが このcopy-on-write friendly patchの原理だ。 GCによるオブジェクト単位での更新がないので、 forkしても本当に書き換えられなかったページはコピーされないまま共有される。
とりあえず動いているみたい。
「20%性能向上*1」とうたっていたのだが、 手元ではそんなに性能が変化するプログラムはなかった。むしろほんのちょっと遅くなる感じ。 ま、forkとか使ってないから当然といえば当然だろう。 キャッシュがとか思ったけど、考えてみればキャッシュは読み込みに効くので、 書き込みの局所化を発生させる今回のパッチは関係なさそう。
誰かforkとGCの組み合わせが原因で遅くなっていることが観測できるベンチマークとかもってないだろうか。 Ruby単体で動き、Railsとかとの組み合わせでない方がありがたい。
自分で試してみたい人はcow-friendly-gc.diffを どうぞ。
パッチを当てるためには
patch -p1 -lU < cow-friendly-gc.diff
とすると良いだろう。
*1 よく見たらpart6のパッチと比較して、だった
宣伝。
2月23日(土)に鳥取県鳥取市の鳥取環境大学で、 「セキュリティキャンプ・キャラバン with プログラミング -鳥取-」が 開催される。
残念ながら私は参加できないが(ちょうど帰国の日だから)、 斎藤先生や、wakatonoさん、竹迫さんのような有名人も来るし、 時間の都合が付けられる人はぜひ参加すると良いだろう。
ってか、なんで私の都合の悪い日にするかな(苦笑)。
私のエントリから派生していろんな人が自分の思うところの「初心者用言語」について 語っている。しめしめ。
あ、そうそう、そのエントリでひとつだけ訂正。
ここから「初心者向け言語が避けていること」言い替えれば「初心者が苦手なこと」が何であるかだいたいわかる。彼らは「抽象化」が苦手なのだ。
誰も突っ込まなかったのが不思議だけど、「初心者向け言語が避けていること」と 「初心者が苦手なこと」はぜんぜんイコールじゃない。 だから、正確には
のどれかだ。結構重要な違いだよね。
さて、いろんな人が初心者向け言語について書いてくれた中にはやや自虐的なものも見られる。
初心者こそPHPを使うべき - 行き詰まった時の気分転換日記
他の言語なら、きっと物知り顔のベテランが出てきて、あれこれ言うんだろうと思う。PHPはそれがない。だってみんな初心者ですから。
初心者には、枯れて面白みもない言語より、PHPのような激しく変化している言語の方が楽しいと思う。
PHPはそれだけ勉強しないといけない言語、まさに初心者にはもってこい。
最もタフになれる「初心者用言語」は Squeak Smalltalk! - sumim’s smalltalking-tos
なにもそこまでいじけなくても。PHPもSmalltalkも良い言語ですよ、きっと。
そういえば、どのような言語が初心者にもっとも良いかについて、 私の意見は述べてなかった。 私の意見は、以下の通り。
言語は関係ない
ひとことに初心者といっても玉石混淆なので、なんとも言えない。 学ぶ気のある人なら、PHPから入ってもCから入ってもLispから入っても 抽象化やらオブジェクト指向プログラミングを身につけるだろう。 今30代、40代くらいの技術者はほぼ全員BASICとかFORTRANとかCOBOLの ような抽象化機能に欠ける言語から入門してるけど、 だからといってほとんどが抽象化を身につけてないというわけじゃない。
しかし、抽象化機能が強力だったり、使わないとろくにプログラムが書けないような言語で 入門した場合、それを身につけそこなう確率が下がるというメリットがある。 一方、現実に抽象化機能を身につけそこなっている人が数多く観測される以上、 そのような言語での入門手段しかない場合、そのような人が プログラミングそのものからドロップアウトすることになる可能性が高い。
私はそれでもいい(質の悪いプログラムを量産されるよりはマシ)と 思ってるけど、世間的にそれで合意ができるとはちょっと思えないな。
でも、「関係ない」ってのは、ちょっと卑怯な答えだよね。
先日、Microsoftで開催されたLang.NETの 結果を受けて、Ruby.NETの開発が中止されたとのこと。
今後、.NET上のRuby処理系はIronRubyに一本化される方向、らしい。
道本さんによるITPro Expoのまとめ。
どうなんだろうね。私のプログラミング人生における目標はお金持ちになることではないので、 適当な役割分担は適切だと思うし、その立ち位置は関係者にはかなり理解してもらえていると思う。 でないと、路頭に迷うわけだし。
rb_mark_table_remove()内にrb_mark_table_heap_remove()と同じ処理が記述されてるんですが、わざとですか?;-p
rb_mark_table_heap_contains()とかも…(汗
GCすると、ヒープのほとんどのページにゴミがみつかるような場合だと、効果があまりないのではないでしょうか。逆に、生きているオブジェクトで多くのページがぎっしり埋まっているような場合があるなら、効果がありそうです。
脊髄反射ですが、キャッシュの効果は書き込みでももちろんあります。
>、「初心者向け言語が避けていること」と「初心者が苦手なこと」はぜんぜんイコールじゃない。
それで一見、初心者向け言語そうでも玄人でも使いやすい言語は
Matzさんから見て、どんな言語が挙げられますか?
初心者、って何ですか?これの定義ができていないと、「初心者向け言語」なんて、作れないと思います。初心者向け言語の最初の定義は、「初心者とは、どういう状態の人か」ではないでしょうか。
で、初心者って、何ですか?
Jittaさん、
私自身は注意して最初から単一の「初心者の定義」に踏み込まないようにしているはずです。
当初のエントリでの「初心者向け言語」というのは、「初心者向けと言われている言語」という意味ですから、そこでの初心者の定義は「それぞれの言語が対象にしている(はず)のユーザー」という以上の意味を持ちません。その上で、あえて共通点を探すとこうなるという論旨でした。
一方、このエントリでは「初心者と言っても玉石混淆である」ということで、統一的な定義を避けています。
ですから、私に聞かれても、という感じですね。
それ以上のことは、個別に「この言語が初心者に向いている」と述べていらっしゃる方に尋ねるより他ないでしょう。
> どのような言語が初心者にもっとも良いかについて
> 言語は関係ない
………………。
長い答えでも言っていますけれども、
・BASICとかFORTRANとかCOBOLのような抽象化機能に欠ける言語
・抽象化機能が強力だったり、使わないとろくにプログラムが書けないような言語
とでは、抽象化の考え方の身に付きかたが違うんじゃないでしょうか?
BASICとかFORTRANとかCOBOLの場合とLispの場合で、最終的に抽象化の考え方を身に付ける人の数は変わらないと言うのでしょうか?
さらにいうと、
・抽象化機能が強力だけれども、初心者でも具体的で扱いやすい言語
・抽象化機能が強力で、具象と抽象の間をシームレスに行き来できる言語
とかが存在したら、初心者でも抽象化の考え方を(他の言語よりは)身に付けやすくなるんじゃないでしょうか?
そもそもDolittleとかLogoとか教育用に設計された言語もありますが、これらは初心者向きではない(抽象化を身に付けるのに相応しくない)ということでしょうか?
私がas I likeにまつもとさんのproxyになってreplyしますが、
>それで一見、初心者向け言語そうでも玄人でも使いやすい言語は
>抽象化機能が強力だけれども、初心者でも具体的で扱いやすい言語
>抽象化機能が強力で、具象と抽象の間をシームレスに行き来できる言語
は、Rubyに決まっているんじゃないですか?
それと、Web2.0社会(?)では、「初心者向け言語」は、「初心者」がWebにdebutしても、火傷をしにくい仕様である必要があるのではないでしょうか?
「の」さん、
そうですね、十分に長いスパンで見れば、最初に使ったのがどのような言語でも、最終的に身に付ける人は付けるし、付けられない人は付けられないのではないかと疑っています。一生ひとつの言語に縛られるわけじゃないので。
あくまでも仮説ですが、
* 抽象化機能が貧弱な言語→理解率が低い
* 抽象化機能が強力な言語→ドロップアウト率が高い
で、最終的に「初心者」を脱出する数はあまり変化しないと思ってるわけです。
証明するのは難しいですが。
DolittleやLogoについては、まだサンプル数が少ないので静観してます。
少なくとも私のまわりの「デキるプログラマ」に「教育用言語からはじめました」という人はあまり多くないですから。
>まつもとさん
これは学習曲線の問題ですね。確かに急勾配の学習曲線を持つ言語ならばドロップアウト率も高いと思います。しかし、それこそ一生ひとつの言語に縛られるわけじゃありませんから、始めは学習曲線の勾配の緩やかな「初心者向け言語」から始めて徐々に抽象化機能を学習するような形になれば、ドロップアウトせずに「初心者」を脱出する確率も増える、と私は考えています。
理想的には一つの言語で抽象<->具象をシームレスに移動できるといいんですけどね。
もちろん抽象化の学習曲線の話になると、言語はしょせん「学習ツール」の位置付けでしかありませんから、良い言語を使ったからといって全てが解決するわけではありません。
ただ、抽象化の学習をスムーズに行うというコンセプトを決めるのならば、その視点で言語を設計することは可能かと思います。
自分ならば
・一貫して使用できる単純なルール
・抽象化した内容も具象化したものと同様に扱える再帰的/入れ子的構造
・目で見て説明できる動作プロセス
あたりを煮詰めてみるところですが……。
やっぱりForthが「初心者(学習用途)向け言語」に近いよなぁ。
あ、あと
・グループ化と細分化
・データ同士の関連性
もあった方が良いですね。こっちはCLOS(総称関数/オブジェクト)ですかね。
私の場合、学習順序としてN88-BASIC,LOGO→C→C++と進み、これに加えてJavaやらPerlやらVBやら、プラットフォームがクロスだったり(これは言語とは関係ないか)、必要に応じて仕事でいろいろやってます。
最初に学習した言語がBASICだからといって、私自身、関数が分からなかったり、グローバル変数しか使えなかったり、メモリ管理とか構造体とかOOPとか関数型言語とか分からないわけではないので、最初に学習する言語はあんまし問題ではない気がします。
が、最初に学ぶ言語のみを使用している期間が極端に長い場合(もしかしてこのケース多い?)、最初に学習する言語の選択はすごく問題になる気がします。多分、N88-BASICを10年も続けてたら…、とんでもないプログラマ(良くない意味で)になっていた気がします。これをPHPを最初に…、に置き換えた場合、どうなるかはPHP使ったことないので分からないのですが…。
ご紹介、痛み入ります。ただお言葉を返すようですが、断じて「いじけ」てはいませんよ(^_^;)(“いじけ”って「(恐怖や寒さに)萎縮する」「(ひねくれて)臆病になる」って意味の言葉ですよね?) これでも、行間でがんがんアピールしていますから、萎縮したり臆病にはなっていないつもりです。「なにもそんなふうにヘソを曲げなくても…」というようなことをおっしゃりたかったとかでしょうか?
そうか、「いじけ」は不適切ですね。
じゃあなんだ、「逆説的」? うーん、違うな。
セキュリティキャンプ・キャラバン with プログラミング -鳥取-
は2月23日(6月ではなく)だと思いますよ。
私も古いBASICから始めました。未だに関数やオブジェクトなどを使うコツがわからないのでRubyやLISPもBASICのように書いてしまいます。概念を理解することとそれを正しく使うことの間にも大きな隔たりがあると思うのですがいかがでしょうか。
きゃーっ、6月だなんて。> よしおかさん
ありがとうございます。直しておきました。
>まつもとさん
>で、最終的に「初心者」を脱出する数はあまり変化しないと思ってるわけです。
一人で勝手に「初心者」から脱出してしまう人が増えないというのなら、そうだと思います。
でも、それでは身も蓋もないですね(笑)
プログラミング言語のいろいろな機能は、その目的がわからないと、結局理解できないんじゃないでしょうか。
たとえばBASICとかHSPとかでGOTO使いまくりでプログラムを書いて、1000行あたりでどうしようもなくなって、そこで周りの言語を見渡すと、関数とかローカル変数とかの機能があってなんて便利なんだと思う、「BASICから入った世代」ってのはだいたいそんな経緯で言語を学んできていると思います。
そういう経緯を踏まず、いきなり最近の言語でプログラミングを始める会社の若いのを見ていると、何か危ういものを感じることがあります。
そういう純粋培養な免疫持たない人達のところに、言語のヘボさをドキュメントで補って実績を上げてきたCOBOL上がりの上司がやってきて、「おまえらもっと『ちゃんとした』開発をしろ」と、クラス名やメソッド名やテーブル名を連番にしたり、フロチャートを書かせたりするわけです。言語はC#なのに。
少なくとも現在開発の中堅である30代とかの人達は、入社時点からCぐらいはあったはずなのに、なんでこんな規則に諾々と従うのかと考えるに、彼らには「免疫」がなかったんじゃないかと思わずにはいられません。
> ですから、私に聞かれても、という感じですね。
ああ、ごめんなさい。まつもとさんに聞いているわけではありません。「いろんな人が自分の思うところの「初心者用言語」について 語っている。」という所に反応して、「その前に、初心者ってなによ?」と、常々思っていることです。
趣味は除いて。仕事でやっているなら、昨日からはじめても「プロ」でしょ、と。
Jittaさん
初心者<=>上級者をX軸とし、アマ<=>プロをY軸とすると、
大まかに言って、初心者andアマ、初心者&プロ、上級者&アマ、上級者&プロという4パターンに類型出来ませんでしょうか?
いちいち訂正してすみませんが、「初心者andアマ」はバグで、「初心者&アマ」が正解です。