C#でParallel Prgoraming

ここで書いているのは、全て個人的な所感です。

勘所

  • 基本的には全てasync/awaitを主体としたプログラム構造にしておく。これはMain関数から全て対応する必要があるので最初のプログラム設計に注意が必要。後でやろうとは思わない方が良い。
  • TPL DataflowのActionBlockやTransformBlockは便利で効率良いので、これを主体に設計していくのは良いかも。
  • async/awaitを使う際は、ConfigureAwaitをちゃんと使わないと結局シングルスレッドになってると言う事があるので気を付ける。COMとかGUIとかで同じスレッドで動かすことを保障してほしい時以外は必ずつけるべし!
  • 新旧のParalleライブラリを混ぜない。Parallel.foreachとか。PLINQとか。混ぜるにしても、必ずパフォーマンスとスレッドの数や使用状況を調べつつ使う事。特にParallel.ForEachは呼び出しもとのThreadをブロックしてしまうので、Taskの中で呼び出すと、それだけでTaskのWorkerThreadが死ぬ。
  • async/await使うなら余程の事がない限り実行中のThreadを止めるようなコードを書いてはいけない。同期をする必要がある場合は、SemaphoreSlim(1,1)に対してawait WaitAsync()で待つ事。
  • lockキーワードは、ビルド後にMonitorクラスを使った実装に展開される。Monitor.EnterはThreadを止める。故にasync/awaitでは使わない方がいい。待つならSemaphoreSlim等使うこと。
  • BlockingCorrectionにAsyncなメソッドは無く、その名の通りThreadをブロックするので使わない。代わりにTPL Dataflow等で代替する。
  • VisualStudio2012では、Taskを戻り値として持つ関数に対して、戻り値を受け取らず、awaitを行わない場合ビルド時Warningを吐くが、基本的に無視しても構わない。念の為に変数で受け取るだけ受けても構わない。
  • Mutexは""LockしたThreadと同じThreadでReleaseする必要がある""ので、Task内で利用する際は適切なTaskSchedularを使って、きちんとハンドリングを行うこと。
  • DefaultのTaskSchedulerは良く動くので使用をお勧めするが、挙動はしっかりと把握した上で利用しないと、Threadが大量に作成されたりするので気をつけること。またWorkerThreadの数を制限するのも良いが、デッドロックの危険性も生まれてしまうので一長一短。
  • TPL DataflowのTransformBlockはドキュメントの説明とは少し異なる動きをする。TransformBlockに対してCompleteを呼んだとしても、Receive/ReceiveAsync/OutputAvailableAsyncを呼び出すまでPostしたものは実行されない。つまりComplete() -> await Completion -> TryRecieveAllはデッドロックする。罠です。
  • HDDへのアクセスはシリアルな方が速いので、出来ればシリアルにする。SSDはこの限りではない。対象によって分けられるなら分けれるようにしておいても良い。例えばアクセス先がネットワーク越しなら、IP事にシリアル、複数IPに対してパラレルとか。

資料

C#で非同期プログラムをやるなら、絶対にこの二つは見て理解するべき。

async/awaitの詳しい動作と使い方が学べる
The zen of async: Best practices for best performance | BUILD2011 | Channel 9

PLINQ/TPL Dataflow等のライブラリの使い方や、ConcurrentExclusiveSchedulerPairの使い方が判る。またTask内において、Threadをsleepなどで止めるとどうなるかが判る。
Building parallelized apps with .NET and Visual Studio | BUILD2011 | Channel 9

ライブラリ

自分用のメモとして、C#で良く使うParallel Programing用ライブラリを載せる

Nito.AsyncEX

TPL Dataflow

Cloud9上のスクリプトファイルをローカルで実行する(Pythonの例)

PreviewをPublicにしていない場合

Cloud9上のファイルへのリンクは、ファイルをダウンロードしようとした際のリンクを利用すると簡単。

例えば以下の様な、pythonスクリプトのダウンロードリンクが手に入った場合

https://hogehoge.cloud9.no.server.death/workspace/script.py?download&isfile=1

downloadとisfileを取り除いたリンクにcurlでアクセスすると、スクリプトの内容がそのままstdoutにでるので、それをpythonにぶっこむ。

curl https://hogehoge.cloud9.no.server.death/workspace/script.py | python -

PreviewをPublicにしている場合

取得されるのはgz圧縮されたものなので、gunzipで解凍しつつpythonにぶち込む。

curl https://preview.c9.io/hogehoge.py | gunzip -c | python -

電子回路シミュレーターNGSPICE

Next Generation Spiceの略で、NGSPICEらしい。
使い方はSpiceと同じ。

誰かAPIでアクセス可能なNGSPICEサーバーとか公開してくれないかなー。

自分で作るしかないかなー。

http://ngspice.sourceforge.net

ギター/ベースのオートチューンマシン「PLEK」

PLEKとは

ギターやベースの状態を、センサーで正確に検出して、チューニングや加工等を行う事が出来る機械

取り扱い先

東京では渋谷のSleekEliteさんが取り扱いをしている模様
http://sleekelite.com/plek/