2012年5月11日金曜日

データフローDSL考 (6) - 並行処理

データフローDSLについてのアイデアメモの続きです。データフローDSLでの並行処理についてです。

データフローDSLを考える上で外せない要素が並行処理です。

今後はますます低クロック&メニーコアの方向にスマートデバイス、サーバーともシフトいくことが予想されます。こういったプラットフォーム上でアプリケーションを高速動作させるためには、アプリケーションが、ネイティブな並列処理プログラムである必要があります。外付けで、部分的というのはダメということです。

もちろん、現行のマルチスレッドプログラミングでは、プログラミングの難易度が高くなりすぎて、一般的なエンタープライズアプリケーション開発の文脈でネイティブな並列処理プログラムを書くことは事実上不可能です。

この目的で期待されているのが関数型プログラミングですね。

データフローDSLを設計する際もこの要因を取り込んでいく必要があります。

関数型プログラミングが並行プログラミングの本命であるなら並行処理の記述に独自のセマンティクスを持ち込むより、関数型プログラミングのセマンティクスを自然な形で取り込んでいくのが自然なアプローチになります。

並行プログラミングの2つの形

並行プログラミングを考える上では、以下の2つの異なったユースケースがあることを意識しておく必要があります。

  • 大規模演算を並行処理して実行時間を短縮する
  • 非同期事象を扱う

応用編として、大規模演算を並行処理して実行時間を短縮するしつつ、随時非同期事象を取り込んでいく、というのもありそうですが、話が発散しそうなので、まずは考えないことにします。

並行処理で時間を短縮

並行処理で時間を短縮することを考える上で重要なのは、処理の開始と終了は同期型ということです。処理の内部では、複数のコアを同時に使用した並列処理を行う場合でも、外部からの見かけは同期型となるわけです。

このような処理の場合も、内部実装に並列処理を陽に記述しなければならないのが現行のマルチスレッドプログラミングの問題点です。

この問題の解決に期待できるのが、Monadicプログラミングです。Monadicプログラミングでは、普通のパイプライン的な処理を書くと、内部的に自動的に並行実行され、自動的に同期してくれるような振舞いを実現することができます。プログラマは普通のMonadicプログラミングをするだけで自動的に並列処理を手に入れることができるわけです。

パイプライン的な処理を逸脱した複雑なデータフローはMonadicプログラミングで直接カバーできませんが、サービス・バス的なメカニズムで克服できるのではないかというのが、ここまでの議論でした。モデル記述の場合は、パイプライン+サービス・バスで記述したグラフ構造によるデータフロー・モデル全体を並列処理させるようなアプローチもあります。たとえば、モデルをコンパイルしてAsakusa Frameworkに落とし込めば可能です。

フレームワークAPI DSLの場合は、サービス・バスによる非同期処理の部分で、手作業的な並列プログラミングが出てくることになりそうですが、この部分を極力小さくできれば、実用的に使えるのではないかと思います。

非同期事象

後者の非同期事象は、関数型プログラミングではアクターで扱うのが一般的だと思います。

並列プログラミングでは、非同期事象の扱いも重要な項目ですが、データフローDSLという意味ではスコープ外と考えてよいでしょう。

あえて考えるとすると、データフローDSL的には、パイプラインを合成するためのサービス・バスの部分で接点が出てきそうです。サービス・バスのチャネルに外部事象の入力を認めれば、非同期事象を扱う事が可能になります。

Monadicプログラミング

パイプライン記述でどこまで並列処理を記述できるのかという点が大きな論点になってきます。

そういう観点で考えてみたのが「関数型とデータフロー(5)」です。以下の図では、ListモナドをKleisli圏で合成していますが、こういったアプローチで並列処理をシンプルに記述できないか、ということです。

最近、ちょっと面白そうに思っているのがScalazのPromiseをApplicative演算で使用することで並列処理を記述する方法です。これは、いずれこのブログでも紹介したいと思います。

いずれにしても、Monad、Promise、Kleisli、ApplicativeといったMonadicプログラミングの要素が、並列処理の記述に非常に適していると考えています。

まとめ

今回はデータフローDSLと並列処理の関係について、アイデアレベルでざっくり考えました。

Monadicプログラミングは、普通の処理を簡潔に記述できる点が現時点の逐次プログラミングでも有効ですが、並列プログラミング時代に入ってくると、「Monadicプログラミングなしにはまわっていかない」、といったプログラミングの中心軸になるのではないかというのがボクの予測です。

データフローDSLのパイプライン記述部も、これらの要素を活かしたMonadicプログラミング記述によるアプローチを軸に考えていきたいところです。

0 件のコメント:

コメントを投稿