CS

A4MMC

September 27th, 2010  |  Published in CS

6月にフランスの Saint-Malo というところで開かれた、 A4MMC という国際ワークショップで発表してきました。 今さらだけどつらつら書き残しておこうと。

ポイント:

  • 初めての英語での発表だった
  • contribution, contribution, contribution!
  • アプリケーションはまだ模索中

A4MMC とは

Applications for Multi/Many Core で A4MMC です。 ISCA というコンピュータアーキテクチャについての国際会議があって、それの併設ワークショップ。マルチコアとかメニーコアとかになってくるけど、じゃあどんなアプリケーションがあるの? という問いに対して、各自アプリケーションを持ちよって発表する、というのがテーマで、今回のが第1回目。 セッションは Cell, GPU, その他 に分かれていて、半日のこじんまりとしたワークショップだった。 採択率は full paper が 7/8 (87%) とだいぶ緩い.. ぼくは half paper として出していて、そっちの採択率は 1/6 (16%) 。全体としては 8/14 (57%)。

初めての英語での発表だった

いやー、さすがに緊張しました。日本語での発表ならなんだかんだで回数重ねてるからなんとでもなるんだけど、英語でしゃべるとかまるで勝手が分からない。15分発表のつもりで用意していたんだけど、当日「10分発表、3分質疑ね」と言われて、ぜんぜん調整できなかった。場数がいるな… ぱたぱたと焦ってしまって、ストーリーを十分に伝えることができなかったのが 反省点。

あと、ちゃんと練習せねばだ。しゃべることは Keynote のメモに書いていて、 iPhone の Keynote remote アプリからカンペとして読んでいたんだけど、やっぱり読み上げプレゼンは伝わらない。日本語でしゃべる場合だと、メモにキーワードだけ書いておいて、しゃべってる最中に文章を組み立てる、というのはアリなんだけれど、英語だとまだその場でさっと文章が浮かばないのがまずいところ。

なので、やるべきは 1. しゃべる英文を丸暗記、 2. 英文をとっさに思いつけるようになる 、の2つ。 2 を目標としながら、 1 でしのぐ、が現実的かな。

質疑応答のときにはいちおう、聞かれたことに対してささっと拙い英文を返すことはできたので、進歩してはいるのだ… では、どうやって即時応答ができるようになってきたかというと、単に量の問題な気がする。国際会議にちょこちょこと足を運んでノリをつかんだり、レセプションに飛び込んだり。ふつうの英会話と同じ。詳しくない話題で盛り上がっている場で受け答えするならいざしらず、発表したことについての質問ならこれまで散々考えてきたことだから答えられないわけはない。

contribution, contribution, contribution!

発表した後の質疑は、「これは Cell でしか動かないの?」「私たちにも使えるようになるの?」といったものでした。つまり、「こんなものをつくったよ」「それはナイスだね。で、我々のコミュニティに対してどういう貢献になるの?」ということだと思う。

当たり前なんだけど、ただ発表するだけじゃ自己満足でしかなくて、そこで得られた知見をどうコミュニティに活かせるか、という視点が足りなかったなーと。研究だけじゃなくて、どんなコミュニティでも言える。この視点が足りなかったから、「一見さん」ぽい立場からいま一歩出ることができなかったんじゃないかな。

学会とか何かのコミュニティに初めて参加したときに感じる「一見さん」感というのがある。周りの人たちはそれぞれに楽しそうに談笑していて、自分がなんかぴたりとはまっていない感じ。

そういうときは発表してしまうに限るんだけど、その内容がコミュニティに対してどれだけインパクトがあるか。を考えておくとよいなーと。

あと、継続して貢献することがキモだなと。点をつなげて線にする。複利効果も期待できる。すごく fundamental なこととかだと単発でもいいんだろうけど、凡人のぼくはホームランを狙うよりヒットでつなげたい。あぁこれはオープンソース活動とかだと当たり前なんだろうな。

アプリケーションはまだ模索中

ワークショップの内容について書いてなかった.. そもそも、並列処理能力を活かせるアプリケーションはどんなものがあるか、というのを知るのが目的で参加していたのでした。けど今回の結論としては、まだみんな模索中だなーというところ。

プランクトンのシミュレーション、巨大望遠鏡、といったアカデミックなアプリケーションというのがまずあり。こういう系は、これまでにあったアプリケーションの規模を大きくするというものなので、あんまり新しい感じはしない。他の発表は、 GPU を MPI でつなぐ、とかオレの FPGA で CUDA を動かしたぜ、とかいう話でこれまたユーザレベルのアプリケーションっていう感じじゃない。

たぶん、もっと他の分野の人たちとの交わりが必要なんだろうなー。じっさいに困っている問題を抱えている人といっしょに仕事をする、という。自分たちの世界で考えてしまうと、どうしてもこれまでの延長になってしまいがちだ。コンピュータを (意識せずにせよ) を使っていて、遅くて困っていることってなんだろう?

そのほか

先に出席していた HotPar ’10 で話した人がちょこちょこといて、声をかけてもらったり、声をかけたりできたのがよかった。点がつながる感じがするよね。継続的にコミュニティに参加して、コミットしていくことが大事だな。

あとは、TGV のチケットがなかなか買えなくてやきもきしたり、ホテルの近辺が城塞都市メルキドっぽかったり、帰りのフライトの日にストライキが決行されて帰るのがやばかったりした。

まとめ

英語の発表、もっと数をこなそう。コミュニティへの継続的な貢献がつながりになる。日没が遅いのは文化に大きな影響を与えるる。

かれこれ1年ほどやってきた研究者もどきの生活もこれで一区切り。これからはまた開発者生活にもどります 。

HotPar ’10

September 7th, 2010  |  Published in CS

6月のことですが、 HotPar ’10 というワークショップに参加していました。

ポイント:

  • 逃げ場がないことのは大事
  • ライブ感

HotPar とは

HotPar そのものについて。 Hot topics in Parallelism というテーマで、 2009 年からはじまった国際ワークショップです。いまのところ、2年連続でバークレーにて開催されています。 で有名なパターソンさんが取りまとめてる。

面白いのは、 参加するなら論文書いてこい というところでしょうか。手ぶらの参加はなしです。これは、コミュニケーションの始めやすさにつながっていてナイスだと思いました。採択率は、論文で 16/68、ポスターで 20/52。1st author 以外も来ていたので、けっきょく50-60人くらいが参加していた。

企業からと学生とが半々くらいで、学生の人たちはたいていどこかの会社 (Intel, Microsoft, EA, …) にインターンに行っていた。日本からはぼくだけ。

やるしかない

自分は、2009年の初回にふつうの聴講者として参加していて、今回はポスター発表するという位置づけ。2009年のときは聴くだけの立場でしかなくて、透明人間になったような辛さがあった。自分がどんなものを持っているのか、誰にでも分かるかたちで見せることができないとダメだと思ったものです。今年はそのリベンジ。世界で動けるように。

そういうわけで、論文を出し、けっきょくポスターとして通った。初日の最後に LT みたいにしてポスター発表者全員が30秒でポスター紹介をプレゼンする、という時間があり、短いながらも初めての英語スピーチをした。すごくあたふたする… いろいろ準備を考えるんだけど、けっきょくしゃべりだしたら思ってたことの3割くらいしか言えないものです。

そんな中で思ったのは、 逃げ場がない ということが大事なんだということ。ネットがつながらないから、心地良い外の世界に逃避できないし、自分しか日本語話者がいないから英語でしゃべらざるを得ないし、他にごはんの手段がないのでテーブルにつかざるを得ない。テーブルについたら、こちらから何もしゃべらないと1,2時間そのまま、というとてもしんどい状態になるので、なんとかして絡んでいくようになる。まぁそうはいっても雑談はむずいわ…

最初に話さないと、ずっと話さない。まず当たっていくことを心がけようとか。軽い話題 (いつから来た、どこから来た) から入って、専門分野の話 (何やってるの、何がいちばん難しい問題なの?) にもって行く、というパターンを覚えたりとか。

そもそも、自分はカンファレンスや勉強会に参加してもロクにしゃべることがなかったんだけど、ここ 2,3年の積み重ねでだいぶコミュ力が培われてきたんだなーという実感。

とはいえ、英語圏のパーティはやはりノリが違うし、まだまだむずいですね… 雑談力を身につけたい。 と同時に、自分の中に、じっくりと考えぬいたものがないと、けっきょくただのおしゃべりにしかならない。深みが魅力になる。やるべきことはまだまだ、まだまだある。

よかったこと

ポスターセッションは、一杯ひっかけながらポスターについてああだこうだと議論する、というスタイルだったこともあり、よく話せた。あまり考えずにしゃべるようになるというか、勢いづくというか。コミュニケーションツールとしてのワインとポスターというのがある。

あと、わりとアジア圏の研究者とはよく話したな。似たもの同士感があるんだろうか? 英語ラクじゃないよね、とか学校でたあとは国に帰るの? (No) とか、そういう話を夜遅くまでしていた。

チャレンジすること

話したものの、その場で終わりになってしまいがちなので、ネットワークを広げたい。たとえば、これに参加したあと、続けて ISCA ’10 というカンファレンスにも出席したんだけど、そこで「ああ、 HotPar でもいたよね、ひさしぶり」といった風に会話が始まることが2,3度あった。コミュニティによく出入りして、アウトプットを出し続けることだな。

あとは考える深さとスピード、雑談力, …

おもしろかったところ

その場でのコミュニケーション、によく気が配られていた。

ランチのときに、各テーブルにトピックがあって (並列デバッグどうやる? アプリはどんなのがある? どう教育する? などなど)、参加者はめいめい好きなトピックを選んで座る。で、ごはんを食べながら 1.5 時間くらいそのトピックについてしゃべる。このスタイルは、学会とか勉強会などで有効なんじゃないかな。初対面の者どうしが同席して話し始めるきっかけとして。コミュニケーションツールとしてのランチディスカッション。

あと、会場ではインターネットが使えない。 Wifi も電源も提供されていない。パターソン曰く「Wifi はここにはないよ。数百ドルも出して参加するカンファレンスで、席に座ってやっていることといったら話も聞かずメールチェック、ではなんとももったいないじゃないか。ディスカッションに参加しよう」。まったくだなー、と。ライブ感、参加している場にある価値といったものが、ネットで損なわれてしまいがちなんだ。

会場はちょっとダウンタウンから離れてるし、近くに店もなく、合宿みたいなノリだった。泊まった部屋もルームシェアリングになっていて、とにかくコミュニケーションが促進された2日間だったな。

ああ、ぜんぜん技術的なことを書いていなかった。主流は、 性能よりも生産性を というところにあったと思う。 100% カリカリに並列プログラムをチューニングするのはコストがかかりすぎるし、人にまるでやさしくない。 80% の性能しか出ないけど、人が考えやすいモデル、というのが今の方向性なんだろう。


出て行って交わると、自分の研究者としての能力がどれくらいか、というのがよく分かる。井の中の蛙にならないように、あっちこっちでアウトプットしないとだな。

Tags: ,

LL Tiger

August 28th, 2010  |  Published in CS

さんに誘われ、 というセッションに登壇させていただきました。

スライドはこちら:

View more from .

ビデオはこちら:

まとめテキストなどは、9月になったら…


2010-09-01 23:45 追記:

スライドと映像とでほとんどのところは言い尽くしているので、大事なところと端折ったところだけ。

メッセージはなんだったか

  • マルチコア時代は、 JVM ベースの処理系が流行るだろう
  • メニーコア時代は、メッセージパッシングが流行るだろう
  • スレッドを生で使うのはない

順に見ていきます。

マルチコア時代は、 JVM ベースの処理系が流行るだろう

この先5年くらいは、まだマルチコアの時代のはず。メモリを共有するいくつかのコアがいる。そこで重要なのはマルチスレッドでの性能であり、そのあたりをきちんと面倒見てくれる JVM を土台とした言語処理系が流行ると見ています。 Scala, JRuby, Jython, Clojure, Mirah などなど。特に、なんでもあり過渡期言語としての Scala に期待があります。

メニーコア時代は、メッセージパッシングが流行るだろう

その先のメニーコア時代になると、 Memory Wall を崩せなくて、ソフトウェアはメッセージパッシングをベースにすることになると予想しています。 Scala や Erlang といったアクターモデルの並列プログラミングができる LL とか。 MPI は Fortran のごとくしぶとく生き残っていそう… とはいえ、これまでの考え方からのギャップがわりと大きいので、現実的にやるとすれば、いま使っているプログラミングモデルはそのままで、下ではメッセージパッシングで処理系ががんばって動く、という方向だろう。

スレッドを生で使うのはない

でまぁ、しばらくはマルチスレッドでプログラムは並列に動くことになるんだけど、スレッドを生で使い続けることはないだろう。これまで十数年とマルチスレッドプログラミングがなされてきたけれど、いまだに難しいとされている。これはつまり、人間には難しすぎるということだ。学会に行っても、けっきょく未解決問題として扱われているわけで、「難しい問題なら、解かずにおこう (そして研究のネタとして生かし続けよう)」というジョークがあるくらいだ。天才にすら難しいマルチスレッドプログラミングが、エンドユーザプログラミングの時代になんとかなるはずがない。スレッドはアセンブリのようなものなのだ。

そんなわけで、いろんな抽象が考えられている。 Grand Central Dispatch とか、まぁいろいろ。その中でも、メッセージパッシングが重要となるだろう。そもそも状態を共有するからマルチスレッドプログラミングは難しいわけで、状態を共有せず、逐一お互いの状態を問い合わせるようにするメッセージパッシングは、いまはまだ主流じゃないかもしれないけれど、この先はわからんものです。

いまがチャンス

並列コンピューティングが常識になった時代に、さすがに C でプログラミングし続けるのはないだろう。もはやパラダイムが変わってしまっているのだ。「過去の資産を活かしたい」とかよく聞くけれど、それはもはや負の遺産だったりしない? ごついふつうの C プログラムを、多大なリソースをかけて並列化するのは、なんともしんどいし、最初から並列に書いてしまう方がすっきりするよね。これから現れる21世紀プログラマは、さいしょから並列プログラミングしててもおかしくないし、むしろそうなってるべき。そんなプログラミングの世界を切り拓いていきたいものです。

新しいパラダイムには、新しいプログラミングモデルがあってしかるべきで、それはたぶん C じゃない。 C はアセンブリ的なものとして残るかもしれないけれど、並列に書くところは別の言語になるだろう。つまり、ついに C からの脱却がありそうなのだ。そして、まだ決定打はどこも出せていない。今がチャンス! なのです。デファクトをとって勝つる!

Tags: ,

画像の二値化を SIMD で高速化する

August 10th, 2010  |  Published in CS

SIMD の練習がてら、 ARM NEON で画像の二値化を SIMD 化してみる。

元コードは、 実践! iPhoneアプリ開発 : カメラアプリの作り方 (4) – 写真にエフェクトをかける で、 RGB から Y に変換するところと、 UIImage とビットマップとをやりとりするところを流用しています。

SIMD 化戦略は、単純なピクセル並列。 RGBA 各1バイトのピクセルを複数ピクセルまとめて処理するだけ。スケーリングとかのアルゴリズムと違って、近傍のピクセルを考慮しなくてよいので、端の処理も気にしないで済む。

RGB は1バイトなんだけれど、 Y に変換する際に 1バイトで表現できる以上の整数値を扱うことになるので、2バイトの整数で計算する。なので8ピクセルの SIMD にしたのが以下のコード:

まぁ分かりやすい。

iPhone 4、 -Os、 2592×1936 な JPG 画像で試したところ、

  • naive な実装 : 0.689s
  • NEON SIMD : 0.613s

と僅差で勝利した.. 詳しく追ってないけれど、最後のメモリ書き戻しのところが遅そう。

あとはこれを VFP でもやりたいんだけど、ちょっとめんどうげな。最初に RGB を float に変換してしまって、 4並列の SIMD でやることになるかな。果たして naive な実装に勝てるんだろうか.. GCC/Clang こわいです。

Tags: , parallel, SIMD

Ruby GIL test

July 29th, 2010  |  Published in CS

ruby 1.9 で、スレッドはネイティブスレッドを使うようになったけど、 GIL があるためにけっきょく実行は serialize されてしまう、マルチコアを活かせないよというのは、まぁ聞いて知ってたんだけど、ほんとにそうなのか試した。

ruby 1.9.2dev on Core 2 Duo な Mac OS X 10.6.2 で動かして ActivityMonitor.app で眺めていたところ、たしかに CPU 使用率は 99% くらい。1つのコアでがんばってなさる。

ちなみに GIL がないという MacRuby 0.6 リリース版で試したところ、以下のような assertion にひっかかっていた。 GCD かな? ソース追ってみないと。

Assertion failed: ((b->flags & flags) == flags), function rb_vm_prepare_block, file dispatcher.cpp, line 1773.

さしあたり、 ticket きっておいた


追記 2010-07-30 09:24 JST

最新版では治ってるよということで ticket が瞬殺されていた。じっさい latest nightly build で試すと、ちゃんと 2 コアを使って計算が行われいるのを確認できた。

M=10000 で、 time $RUBY_VM gil_test.rb として計測した結果:

  • ruby 1.8.7 : 100%, 69.3s
  • ruby 1.9.2dev : 100%, 22.6s
  • MacRuby 0.7 : 191%, 6.85s
  • JRuby 1.5.1 : 178%, 21.9s

MacRuby が圧倒的な速度である。まあほんとうは VM の起動時間とかを含めないように、 time じゃなくて benchmark.rb とか使うべきなのかもだけれど、ユーザの体感時間という意味で。

Tags: ,

PHP, Concurrency

July 29th, 2010  |  Published in CS

PHP もずぶの素人なのでつっこみ歓迎です。

PHP には、スレッドがない。 fork/exec などのプロセス操作 API を使ってプロセスを使い、プログラムのうち並行実行したいところを別プロセスとして動かすそうな。

そもそも、 PHP で並列処理をしたいことってあるのかなぁという。どこかあちこちにあるサーバからデータをひっぱってきて、元リクエストのためのページをひとつつくる、というシチュエーションで、あちこちのサーバごとにリクエストを投げるところを並行実行したい、というところくらいだろうか今のところ。未来の PHP が、受け取ったパラメータをもとにレイトレーシングなんかしてみて、その結果画像をクライアントに返す、とかいうストーリーがあると、 PHP でももう少しかんたんに並行処理を書きたいよね、とかじゃぁ新しい言語 (方言) をつくるぜ! みたいな流れができてくるのかもしれないな。

まとめてしまうと、 PHP のスレッドサポートは特になく、プロセス単位で create /fork などしろと。うむむ… 重そうである。まだあんまし、進んでいないのかなぁというのと、実際のアプリで並列処理するものがまだ少ないんだろうかなぁというのと、 PHP のユーザ層がライトなものだからかなぁというのと。


関連エントリ:

  • Perl, Concurrency

元ネタ:

let GCD deadlock

July 28th, 2010  |  Published in CS

夏だし、 Grand Central Dispatch (GCD) をデッドロックさせてみたい。

さらっとぐぐって見つけた、デッドロックさせるコードはこんなかんじ:

  void deadlock_1()
  {
     dispatch_queue_t q = dispatch_queue_create("org.deadbeaf.gcd3", NULL);
     dispatch_sync(q, ^{
        printf("in 1\n");
        dispatch_sync(q, ^{
           printf("in 2\n");
        });
     });
  }

で、まぁたしかに処理がすすまなくなる。

でもこのコードからはなんだか、デッドロックというか自分を追い越せないだけな感じを受ける。ひとつのキューがあって、そこにつっこまれた人が、自分が終わる前に他のものをつっこんでいて、無限に待つという。

デッドロックというのは、2つ以上の共有資源があるときに、かたっぽ (A) を自分 (α) のものにしていながら、もうかたっぽのもの (B) をとろうとして、でも B はだれか (β) さんがロックしていて、で β さんは A がほしくて、というすくみの状況を言うんじゃなかったっけか。

というのを踏まえて、以下のように書いてみた。共有資源は 2 つ、 GCD の serial queue は、リソースを占有したいときに使うはず なので、 queue もそれぞれ用に 2 つ。

  void deadlock_2()
  {
     __block int shared_resource_1 = 0;
     __block int shared_resource_2 = 0;

     dispatch_queue_t q1 = dispatch_queue_create("org.deadbeaf.gcd1", NULL);
     dispatch_queue_t q2 = dispatch_queue_create("org.deadbeaf.gcd2", NULL);

     dispatch_group_t group = dispatch_group_create();
     dispatch_queue_t the_q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

     dispatch_group_async(group, the_q, ^{
        dispatch_sync(q1, ^{
           printf("in q1\n");
           dispatch_sync(q2, ^{
              printf("hello from q1->q2\n");
              shared_resource_2 = 3;
           });
           shared_resource_1 = 5;
        });

     });

     dispatch_group_async(group, the_q, ^{
        dispatch_sync(q2, ^{
           printf("in q2\n");
           dispatch_sync(q1, ^{
              printf("hello from q2->q1\n");
           shared_resource_1 = 11;
           });
           shared_resource_2 = 7;
        });
     });

     dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
     dispatch_release(group);
     dispatch_release(q1);
     dispatch_release(q2);
  }

これだと、うまくいくときは


%  ./gcd_deadlock
in q1
hello from q1->q2
in q2
hello from q2->q1

となるんだけど、タイミングによっては


./gcd_deadlock
in q1
in q2
....

と無限に待つ。デッドロックが起きているのだ。


まとめると、 GCD でもデッドロックはわりと容易に起こりうるなぁと。で、それがかんたんに検出できるんだったらいいんだけど、そこは pthread mutex における検出のむずかしさとあまり変わらないんじゃないかなぁというところ。

Tags: ,

Perl, Concurrency

July 28th, 2010  |  Published in CS

Perl をつかった並行プログラミングをしらべていた。 Perl はずぶの素人なのでつっこみ希望です。

歴史

  • 5.005-5.6 までは thread パッケージをつかっていた。 green | native ?
  • 5.6 から ithread (interpreter thread) が入り、 thread ごとに VM が割り当てられるように。 native thread で、共有変数は明示的に shared とつけないといけない。 default で shared nothing.
  • 6.0 から STM が入るらしい。 atomic 構文。他に、 async block という構文ができて、どこかのスレッドで非同期実行させることができる (これは 5.10 でも use Thread qw(async) とすれば使えるな..)。 hyper, cross, reduction operator はデータ並列として扱えるようになっていて、コンパイラが並列実行するコードを出力できる
  • 最近の流行りは、サーバサイドでたくさんのリクエストを高速にさばくための非同期 I/O で、イベントを処理する POE, AnyEvent, Coro といったライブラリ/フレームワークがある

5.005-5.6 ではスレッドが並行処理の道具としてあった。5.6 で入った ithread は shared nothing なのがグー。 6.0 からは野心的な構文ががが。ライブラリ方面では、非同期 I/O まわりがホット、といったところでしょうか。

印象

ithread の multi VM のつくりは、 Ruby でいう GIL, Python でいう GVL がないそうでスケールしそう。 VM をまたいだやりとりは shared な変数を使うんではなくてメッセージパッシングでやるのがいいんじゃないかなぁとか。アクター、アクター。

情報元

Tags: , perl

モディファイヤキーつきでキー入力をエミュレートする

May 15th, 2010  |  Published in CS

Mac アプリをつくっててだいぶハマってしまったのでその小話。

キーボード入力をエミュレートするには、 Foundation の CGEventCreateKeyboardEvent() を使うのが基本です。ドキュメントにもそう書いてある。

Quartz Event Services Reference:

CGEventRef event1, event2, event3, event4;
event1 = CGEventCreateKeyboardEvent (NULL, (CGKeyCode)56, true);
event2 = CGEventCreateKeyboardEvent (NULL, (CGKeyCode)6, true);
event3 = CGEventCreateKeyboardEvent (NULL, (CGKeyCode)6, false);
event4 = CGEventCreateKeyboardEvent (NULL, (CGKeyCode)56, false);
56 はシフトキーを表し、 6 は z キー。つまり、大文字の z (‘Z’) をタイプするよというサンプルコード、のはずなのですが、 Mac OS X 10.6.3 でやってみてもまるでうまくいかない。たんに z が入力されるにとどまります。

で、ぐぐっていると スタックがオーバーフローして:

CGEventRef event1, event2;
event1 = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)6, true);//'z' keydown event
CGEventSetFlags(event1, kCGEventFlagMaskShift);//set shift key down for above event
CGEventPost(kCGSessionEventTap, event1);//post event
のように、 CGEventSetFlags() をかまして、モディファイヤキーが押されているのをイベントに修飾せよ、とある。なるほど。

それでやってみると、たしかに Z が入力されます。I’m feeling lucky! と思うもつかのま、こんどは z に戻らない。むむむ、これは…

そこから一週間ほどもがいていたのですが、状態をリセットすればいいんじゃなかろうかと気づいてやってみたらうまくいった。バッドノウハウすぎるだろこれ..

けっきょくうまくいったコードは以下のようなものになりました。

- (void) postKey:(uint16_t) key withModifiers:(uint16_t) modifiers down:(BOOL)down
{
   CGEventRef event = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)key, down);


if (modifiers & MODE_SHIFT) { CGEventSetFlags(event, NSShiftKeyMask); } else if (modifiers & MODE_CONTROL) { CGEventSetFlags(event, kCGEventFlagMaskControl); } else if (modifiers & MODE_OPTION) { CGEventSetFlags(event, kCGEventFlagMaskAlternate); } else if (modifiers & MODE_COMMAND) { CGEventSetFlags(event, kCGEventFlagMaskCommand); } else CGEventSetFlags(event, 0); // <<<<<<< これ
CGEventPost(kCGSessionEventTap, event); CFRelease(event); }

CGEventSetFlags に指定するフラグは OR でとればよいので、もっとかんたんに書けるはず。しかし今夜はここで力尽きた..


教訓: 仕様、コードに一致していないドキュメントはむしろ害になり得るので気をつけよう。自戒自戒。

Tags:

Grand Central Dispatch をためす (1)

August 29th, 2009  |  Published in CS

Snow Leopard がでましたね!

OpenCL と Grand Central Dispatch がおもしろそうなので、そのへんのことを書いていくシリーズです。まずは Grand Central Dispatch について、手がかりのない状態からかるく使ってみるまで。

0. Grand Central Dispatch について

前に少し書いたように、Snow Leopard から入る並列実行基盤ですね。

1. Xcode でドキュメント探し

Xcode のドキュメントビューア (えらくインターフェイスがかわった) から、 Grand Central とか Dispatch とかをキーワードにして検索すると、それらしいタイトルがひっかかります。しかし、内容をみることはまだできないみたい。 ADC の上級メンバーならよいのでしょうが、ヒラ会員の我々は無理なの?

2. カンをつかう

mdfind dispatch とかしてみるわけです。すると

/usr/share/man/man3/dispatch.3

とかひっかかる。これはあやしい。 というわけで man 3 dispatchman 3 dispatch_async としていくと、概念を紹介するためのサンプルコードが書かれている man ページにあたります。ビンゴですね。

3. 書いてみる

6-9 行がミソですね。 global queue に、ブロックないの処理を非同期で実行するようつっこんでるわけです。

4. 実行してみる

% ./a.out
hoge
... (寝てる)
%

ちゃんと非同期で実行されてます。

5. 確かめてみる

gdb であそんでみましょう。

% gdb a.out
(gdb) b 7           # ブロック内で break
(gdb run
Starting program: /Users/mootoh/gcd_sandbox
[Switching to process 10433]


Breakpoint 1, __main_block_invoke_1 (.block_descriptor=0x100001080) at gcd_sandbox.c:7 7 printf("hoge\n");

とまりました。 switching to process とかでてますね。スレッド切り替えがおこったのでしょう。

(gdb) bt

0 __main_block_invoke_1 (.block_descriptor=0x100001080) at gcd_sandbox.c:7


1 0x00007fff85bc2dc7 in _dispatch_call_block_and_release ()


2 0x00007fff85ba1341 in _dispatch_worker_thread2 ()


3 0x00007fff85ba0c80 in _pthread_wqthread ()


4 0x00007fff85ba0b1d in start_wqthread ()



wqthread とな。 Worker Queue thread とかかな? スレッド全体をみてみましょう。

(gdb) info threads
* 2 port# 0x417 __main_block_invoke_1 (.block_descriptor=0x100001080) at gcd_sandbox.c:7
  1 port# 0x903 0x00007fff85bc1ace in __semwait_signal ()
(gdb) thread 1
(gdb) bt

0 0x00007fff85bc1ace in __semwait_signal ()


1 0x00007fff85bc195d in nanosleep ()


2 0x00007fff85c0f320 in sleep ()


3 0x0000000100000e94 in main (argc=1, argv=0x7fff5fbfe9b0) at gcd_sandbox.c:10



ちゃんと元スレッドがいますね。

6. その他

そういえば、 gcc に何のオプションも指定することなく、ふつうに Grand Central Dispatch のブロック構文が使えていました。また、特になにかライブラリをリンクすることもなく、ただ gcc -g gcd_sandbox.c これだけでビルドできて並列実行できるバイナリが生成されますね。うむむ。

7. まとめ

ADC ヒラ会員なので、まとまったドキュメントとして man 3 dispatch 周りだけをたよりに Grand Central Dispatch を覗いてみました。ブロック構文がちゃんと使えることをまず確認し、 gdb からもちゃんとマルチスレッドの動作が見える、というところまでを追いました。

あと気になるのは、ハイレベル API がどういうものなのか、というところです。 Cocoa 的なのがあるとすれば、 .framework にまとまってるだろうと思うのですけれど、それらしきものはまだ見つけられていません。

次回はもう少し掘り下げてみたいとおもいます。それまでにドキュメント手に入るようにならないかなぁ…

20009-09-02 21:13 JST 追記

その2 を書きました。

Tags: , , 技術紹介