«前の日(07-30) 最新 次の日(08-01)» 追記

Matzにっき


2003年07月31日

_ [機械]VAIO U101

新しいオモチャ。

とりあえずLinuxがインストールできるかどうかも分からないので、 しばらくWinXPのまま使っている。 といっても、とても使い物にならないキーボードなので、 Webを見たりとかそれくらい。

無線LANの設定とかが分からず悩む。 MACアドレスはどうやって得るのかとか、 なぜ「接続不可」と言われるのかとか、 そう言われているのにインターネットにアクセスできるのはなぜとか。

ドキュメントはたくさんあって、いろいろ教えてくれるような気がするのだが、 勘が働かないせいもあって欲しい情報がどこにあるのか見つけることができない。

でも、とりあえず動かないソフトがない、できないことがない、というのは 嬉しいことなのかもしれない。

これからどうするか。

VMwareをインストールするか、Linuxに切り替えるか、Cygwinを入れるか、 家族のマシンにしてしまうか。


2004年07月31日

_ 素晴らしきハッカー ---Great Hackers---

Paul Grahamの新しいエッセイ(翻訳はshiroさん)。 ハッカーの生態について。

まあ、当たってると思う。もし私が本当にハッカーだったとしたら、だけど。

この業界、一番重要なリソースは人間だ、 というわけで、Rubyに関連する活動を見てこの人はと思う人に目をつけておいて、 「仕事を探してる」というタイミングで適切に声をかけるようにしている。

私の紹介で(株)ネットワーク応用通信研究所に入社した人も多いが、 そういう人たちはうちの宝だと思っている。きっと社長もそう思ってるんじゃないかな。

そのうち、Rubyとかオープンソースとかの梁山泊みたいになるといいなあと思っているのだ。 そのためにも本業は安泰でないとな。

しかし、油断していてはいけない。 同じようなポジションをグッデイの前田さんも 狙っているに違いない(笑)。

_ [教会]活動中止

今日は海辺でバーベキューの予定であったが、台風来週のため中止に。 子供たちはちょっと残念そう。でも、波にさらわれてもいかんしなあ。


2005年07月31日

_ [知財] デジタル放送の「コピーワンス」が運用見直しへ−年内に結論。家庭内IP伝送も視野に

日曜はあまり技術ネタは入れない方針なのだが、今日は特別。

朝、新聞読んでたらこんな記事が。リンクはAV Watchから。

2004年4月からBSデジタル放送と地上デジタル放送に導入されている「コピーワンス」が見直されることとなった。29日に開催された総務省情報通信審議会で中間答申が提出され、コピーワンスに関して、今秋より検討を開始、年内を目処に結論を出す予定が明らかにされた。

審議会では、2011年のデジタル放送全面移行を推進するにあたり、「複製は私的録画の範囲内」という観点から、「コピーワンスの現行の運用を固定化する必然性はなく、私的利用の範囲で視聴者の利便性を考慮して運用の改善に関係者一体となって対応していくことが必要」と指摘。

HDDレコーダの普及拡大にあわせて、アナログ放送のルールによるダビング/編集になれた視聴者が急増しているが、「こうした状況下で視聴者の不満を放置すれば、2011年に向けた受信機の普及にとって大きな障害があるおそれがある」とする。

だそうだ。私が今まで書いてきたことが少しでも影響があったとは思わないけれども、 少しはマシな世の中になりそうなのが喜ばしい。

しかし、

そのため、9月をめどに関係者による検討の場を設け、対応に着手、年内に結論を出すことを目標に活動を開始する。放送事業者では、「コピーワンスの現在の運用にこだわるものでなく、私的録画の範囲で、視聴者の利便性のためコピーワンジェネレーションの運用取り決めの見直しに対応する」としており、具体的な方策としては「ムーブが完全に行なわれてからオリジナルを消去」や、「私的利用の範囲に限定される家庭内IP伝送」などについて技術的に実現する方向で検討する。

とあるように、実際には「コピーワンスフラグは原則使わない」という理想的な状況ではなく、 「原則コピーワンス。運用がちょっと柔軟に」くらいになる可能性もあるので、 予断は許さない。

_ [教会] 松江

「今日こそは司会」と思ってたんだが、また違った。おかしいなあ。 どうやら来週らしい。

日曜学校の時間、末娘をだっこして歩き回りながらレッスンを聞いていた(あんまり集中できなかった)以外はごく普通の日曜日。

神権会のテーマは「ポルノグラフィー」。こういう具体的なテーマだと気恥ずかしくなってしまうが、 最近のモラルの低下やら家庭の崩壊などを含む様々な問題に取り組むにあたって 重大な因子ではある。


2006年07月31日

_ [OSS] オープンソースラボ開設式典

松江市が中心になってこの度開設された「オープンソースラボ 〜Ruby City Matsue〜」の開所式が開かれた。

松江市長があいさつしたり、 地元の偉い人(市会議員さんとか)が来たり、 地元テレビ局が来たり、 新聞やテレビのインタビューを受けたり、 TVの夕方のローカルニュースに登場したりしてしまった。

なんだかおおげさなことになってしまったなあ。

ニュースを見た長女には「お父さんっ、なんで一人だけジーンズなのよっ」などと怒られてしまった。いいじゃん、これが私の普通なんだからさ。

_ 歓迎会

先週付けで中途入社した人の歓迎会。

結局テルサ(オープンソースラボのある建物)にあるレストランで。 楽しんだ。18人で、お店のビールを全部飲んでしまったらしい。

_ [Ruby] ドリコムソフトウェアコンテスト:Drecom Award on Rails

昨日、式典があって受賞作が発表になったそうだ。 私は行けなかったのでビデオ出演

私が選んだ「小槌」は、大賞もゲットしたらしい。すげーっ。

CNET Japanに記事も出ていた


2007年07月31日

_ [Ruby] Rubyビジネス・コモンズ: 設立総会

設立総会。超地味なRuby Associationとは違って、 この設立総会は立派なものだ。 福岡県知事も来たりするし。 出席者も300人以上いたんじゃないかな。

で、「Rubyの未来」と題した講演を行う。 まあ、これまでの技術的動向の変化の方向と 現在のRubyの立ち位置から、Rubyの未来を(無責任に)予想する というような内容。

しかし、こんなに多くの人がRubyに注目してもらえるというのは、 ありがたいことでもあり、はずかしいことでもあり。

本物の「Rubyバブル」が来ていることを実感する。 今はイメージ先行で中身の薄い風船に、 これからは中身を詰めていかねばならない。

その後、懇親会ではいろいろな人と挨拶する。 昨年12月のイベントでは名刺が尽きて申し訳ない思いをしたので、 今回はかなり多めに名刺を持参したのだが、 やはり途中でなくなってしまった。

NaClのだけでなく、楽天フェロー名刺までなくなるとは予想外だ。 福岡の人は名刺交換が好きだとか。

いずれにしても、次回があれば今回以上に名刺を持参しようと思う。

二次会では胴上げされた。長いこと生きてたけど胴上げされたのは初めてだ。 普段接することのない体育会的ノリに新鮮な驚き。

_ [Ruby] Three years with Ruby on Rails

Railsが世に出てちょうど3年、という話。 たった3年なのか。

Railsは世界を変えてしまった。 特に私の周りの世界を。

もうちょっと地味に行くつもりだったんだけど、 冷静に思い返してみれば、私以外の人にとっては、今の方が幸せな世界ではないかと思う。 Railsが呼び水になって、動的言語(やLispっぽい言語)の認知度が高まっているし、 技術者の幸せをともなう生産性の高さが「普通の人たち」の間で 語られるというのはソフトウェア業界はじまって以来のことではないだろうか。

これからも世界は変わりつづける。 その中心に近いところに居られたら、と願う。

_ 世界に“コンピュータ”は5つあれば足りる − @IT

「世界に“コンピュータ”は5つあれば足りる」というのは、 IBMのワトソンが語ったとされる有名な言葉だが、 実は本当にワトソンがそのように行ったと言う証拠はないそうだ。

で、その時とは違う文脈で「5つあれば足りる」という話。

つまり、少数の「コンピューティングファーム」が計算能力を提供し、 普通の人は「端末」からそのパワーを利用するという中央集権モデルが 現実になりつつある。

これまでの「分散」の流れはなんだったの、という気にもさせるモデルだが、 コンピューティングの歴史では集中と分散は振り子のように繰り返しているので、 これからしばらく(Webのおかげで)集中に振れそうだ、という予測なのだろう。

おそらく、その次はデータセンターのサイズや電力などの物理的限界と P2Pのような技術によって分散に振れるんじゃないかなあ。


2013年07月31日

_ mrubyのmrb_gc_arena_save()/mrb_gc_arena_restore()の使い方

Twitterで質問を受けたので、 mrubyのmrb_gc_arena_save()/mrb_gc_arena_restore()の使い方 という解説を行った。が、1つ140文字のTwitterでの解説にはどうしても無理があるので、 こっちでまとめることにする。

まずは、Twitterの発言*1はこんな感じ。

arenaの目的。利用中のオブジェクトはGCに回収されないよう保護する必要がありますが、Cのスタックはポータブルに参照できません。そこでC関数実行中に生成したオブジェクトは全部「生きている」とみなす事で保守的に保護します。 yukihiro_matz 2013-07-31 08:16:45
arenaの目的(2)。この保護のためにオブジェクトを記録しておく領域がarenaです。mrubyではデフォルトで100個のオブジェクトを登録できます。 yukihiro_matz 2013-07-31 08:19:02
save/restoreの仕事。現状arenaのサイズは固定なのでC関数実行中にあまり沢山オブジェクトを生成するとarenaが溢れます。そこで沢山オブジェクトを生成する前後にsave/restoreを置くことでarenaのサイズを復元し、溢れを回避します yukihiro_matz 2013-07-31 08:27:02
save/restoreの使い方。オブジェクトを生成する領域の前後をsave/restoreで囲みます。ただし、囲まれた範囲内のオブジェクトが保護されなくなりますから、どうしても必要なものはrestore後mrb_gc_protect()で改めて保護してください。 yukihiro_matz 2013-07-31 08:33:61

これを再度まとめてみよう。

mrubyをCで拡張していると「arena overflow error」という「謎のエラー」に悩まされることがある。 これはmrubyで「保守的GC」を実現している「GC arena」という領域があふれたというエラーだ。

GC(ガーベージコレクター)は、オブジェクトがまだ「生きている」、 つまり、プログラムのどこかから参照されているかどうかを判定する必要がある。 これはルートと呼ばれる参照から直接・間接に参照可能かどうかで判別する。 ルートには、ローカル変数・グローバル変数・定数などが含まれる。

プログラムの実行がmruby VMの中でおさまっている時にはこれは問題ない。 VMの持つルートはすべてGCからアクセス可能だからだ。

問題はCで記述された関数を実行中の時。 Cの変数から参照されたオブジェクトも「生きている」わけだが、 mrubyのGCはCの変数の内容を感知できないので、 C変数からしか参照されていないオブジェクトは死んでいると誤解してしまう。

まだ生きているオブジェクトを回収してしまうのは、GCとしてもっともやってはいけないバグだ。

CRubyでは、Cのスタック領域を無理やりスキャンすることで、 Cの変数をルートとしてチェックしている。 もちろん、Cのスタックを単なるメモリ領域としてアクセスするわけだから、 それが整数を意味する値なのか、ポインタ値を意味する値なのか判別することはできない。 しかし、まあ、そこは「ポインタのように見える値は安全側に倒してポインタだと思って処理する」という 方針で処理している。この「安全側に倒す」というポリシーのことを「保守的」と呼ぶ。

され、このようなCRubyの「保守的GC」にはいくつか問題がある。

その最大のものは「移植性のある方法でスタック領域にアクセスする方法がない」ということだ。 つまり、移植性の高さを実現しようとするmrubyのような処理系では使えないってこと。

そこで、mrubyは別の方法で「保守的GC」を実現した。

問題なのは、C関数実行中に生成されたオブジェクトで、 Rubyの世界から参照されてないオブジェクトのうち、 C変数からは参照されているのでまだゴミ扱いしてはいけないものが存在する、 ということだ。

既に述べたようにCRubyは、Cスタックをスキャンしてゴミのように見えるがゴミでないものを保護している。

しかし、その方法が使えないmrubyは、より保守的なポリシーを採用した。 つまり、C関数実行中に生成されたオブジェクトは、極端に安全側に倒して、いっそ全部生きているとみなせば、 少なくともゴミでないものを回収してしまう問題は回避できるんじゃないかと。

この結果、本当はゴミであるものを回収できないので、若干効率が下がることになるが、 移植性が高いまま、保守的なGCを実現できることになる。 CRubyで時々発生する「最適化で参照が削除されてゴミでないのにGCされた」問題とも無縁になる。

このポリシーで、「C関数実行中に生成されたオブジェクト」を登録しておくテーブルが 「GC arena」である。arenaはスタック状になっていて、 C関数の実行が終わるとその間に登録されたオブジェクトはポップされる。

原則としてはこれだけで、普通の場合は、これでめでたしめでたしなのだが、 GC arenaの存在は別の問題を引き起こすことがある。 これが前述した「arena overflow error」だ。

メモリが少ない環境でも動作することを考慮したmrubyはarenaのサイズを固定長にしており、 しかも、そのサイズはデフォルトで100とかなり小さめに設定されている。

実は当初はサイズ1000とかちょっと大きめにしていたのだが、 このテーブルサイズが厳しい環境があったのと、 後述するようなテクニックを使い、適切にarenaを管理すれば100でも普通に動くので、 現状は100にしている。

その結果、C関数の実行中に数多くのオブジェクトを生成すると、 arenaがあふれることになる。

その対策に用いるのが、表題のmrb_gc_arena_save()とmrb_gc_arena_restore()というふたつの関数である。

int mrb_gc_arena_save(mrb)はGC arenaの現在のスタック位置を返し、 void mrb_gc_arena_restore(mrb, idx)はarenaのスタック位置を保存された位置に戻す。

int arena_idx = mrb_gc_arena_save(mrb);

...なんかオブジェクトを作る処理...
mrb_gc_arena_restore(mrb, arena_idx);

というような使い方をする。

もともとのC関数の実行は、このようにsave/restoreに囲まれているのだが、 一時的にオブジェクトを作り、その後は不要になる領域を 明示的にsave/restoreを囲むことにより、arena overflowを避けるわけだ。

とはいうものの、具体例を見ないとわからないケースもあるだろう。 ここでは、Array#inspectのソースを見てみよう。

static mrb_value
inspect_ary(mrb_state *mrb, mrb_value ary, mrb_value list)
{
  mrb_int i;
  mrb_value s, arystr;
  char head[] = { '[' };
  char sep[] = { ',', ' ' };
  char tail[] = { ']' };

  /* check recursive */
  for(i=0; i<RARRAY_LEN(list); i++) {
    if (mrb_obj_equal(mrb, ary, RARRAY_PTR(list)[i])) {
      return mrb_str_new(mrb, "[...]", 5);
    }
  }

  mrb_ary_push(mrb, list, ary);

  arystr = mrb_str_buf_new(mrb, 64);
  mrb_str_buf_cat(mrb, arystr, head, sizeof(head));

  for(i=0; i<RARRAY_LEN(ary); i++) {
    int ai = mrb_gc_arena_save(mrb);

    if (i > 0) {
      mrb_str_buf_cat(mrb, arystr, sep, sizeof(sep));
    }
    if (mrb_array_p(RARRAY_PTR(ary)[i])) {
      s = inspect_ary(mrb, RARRAY_PTR(ary)[i], list);
    }
    else {
      s = mrb_inspect(mrb, RARRAY_PTR(ary)[i]);
    }
    mrb_str_buf_cat(mrb, arystr, RSTRING_PTR(s), RSTRING_LEN(s));
    mrb_gc_arena_restore(mrb, ai);
  }

  mrb_str_buf_cat(mrb, arystr, tail, sizeof(tail));
  mrb_ary_pop(mrb, list);

  return arystr;
}

実際のコードをそのまま引用してきたので、若干複雑になっているが、 Array#inspectの処理の本質は、 配列の各要素をinspectメソッドを用いて文字列化した上で、 それらを結合して配列全体のinspect表現を作ることにある。

全体のinspect表現の文字列を作ってしまえば、 処理途中に生成した各要素の文字列はもはや不要になる。 ということは、GC arenaにこれらのオブジェクトを登録しておく必要もない、ということだ。

そこで、ary_inspect()関数では、

  • mrb_gc_arena_save()でインデックスを保存
  • 要素のinspect表現文字列を取得
  • 生成中の配列inspect表現文字列に結合
  • mrb_gc_arena_restore()でインデックスを復旧

という手順により、arena領域の消費を抑えている。

ここで注意すべき点は、最終結果となる配列inspect表現となる文字列は、 mrb_gc_arena_save()の呼び出しよりも前に生成していることである。 こうしないと、必要なオブジェクトがGCで回収されてしまうことになる。

処理のパターンとしては、さまざまな一時オブジェクトを生成した上で、 そのうちの一部だけを参照し続けるというケースも考えられる。 このようなケースでは、ary_inspect()のように既存のオブジェクトに結合するような手は 使えないので、mrb_gc_arena_restore()の呼び出しの後に mrb_gc_protect(mrb, obj)を呼び出して、そのオブジェクトをarenaに再登録する必要がある。 ただし、mrb_gc_protect()は注意して用いないと、これ自身がarena overflow errorの原因になることがあるので 注意するように。

などということを、Twitterだけで説明するのは現実的じゃないよなあ。

追記

あ、そうそう。

このmrubyのAPIには、改善が必要だなと思ってる点があって、 その最大のものは、トップレベルでmrb_funcall()を呼ぶと GC arenaに戻り値が登録されるのでそのうちarena overflow errorになることだ。

戻り値を使わないmrb_funcall()のようなものを用意すればいいんだと思うんだけど。 いい名前が思いつかないんだよなあ。

*1 tDiaryにTwitterの発言を引用するプラグインが欲しいなあ


«前の日(07-30) 最新 次の日(08-01)» 追記