3

私は非常に迅速に非常に並列にすることができると私が信じている画像処理ルーチンを持っています。各ピクセルは、隣接ピクセルに対して行われる操作に依存しないように約2kの操作が行われる必要があります。そのため、作業を異なる単位に分割することはかなり簡単です。

私の質問は、私が最速のスピードアップを得るために、この変更に取り組むための最善の方法は何ですか?

理想的には、私が探しているライブラリ/アプローチはこれらの基準を満たすべきです:

  1. まだ5年後です。それほど遠くない将来、CUDAやATIの亜種のようなものが、ハードウェア固有ではないソリューションに置き換えられる可能性があるので、もう少し堅牢なものが欲しいと思います。私のCUDAの印象が間違っている場合は、訂正を歓迎します。
  2. 早く実装してください。私はすでにこのコードを書きました、そしてそれは非常にゆっくりですが、それはシリアルモードで動作します。理想的には、私は自分のコードを並列になるように再コンパイルするだけですが、それは幻想的かもしれないと思います。私がそれを別のパラダイムを使って(つまり、シェーダか何かとして)書き直すならば、それはそれでも大丈夫でしょう。
  3. ハードウェアに関する知識をあまり必要としません。スレッドや操作ユニットの数を指定する必要はなく、使用しているマシンに基づいて自動的に何かを自動的に把握できるようにしたいと思います。
  4. 安価なハードウェアで実行可能にします。それは150ドルのグラフィックカード、あるいは何でもいいかもしれません。
  5. Windows上で実行可能にします。 GCDのようなものが正しい電話かもしれませんが、私が目標としている顧客ベースはすぐにはMacやLinuxに切り替わらないでしょう。これは質問に対する回答をにするのとは少し違うことに注意してください。この他の質問

どのライブラリ/アプローチ/言語を検討する必要がありますか? OpenMP、CUDA、GCDなどを調べましたが、他に欠けているものがあるかどうか疑問に思います。

私は今シェーダやopengl 2.0のようなものに傾いていますが、そのようにすることができるメモリアクセスの数がわからないので、それは正しい呼び出しではないかもしれません。たくさんの方法があります。

5 답변


1

最も簡単な方法は、画像を並列に処理できる部分の数(コアによっては4、8、16)に分割することです。それからちょうど各部分のための異なったプロセスを動かしなさい。

これを具体的に行うことに関しては、OpenCLを見てください。それはベンダー特有ではなく、NVidiaとATIの両方がそれをサポートすることを望んでいるので、それはうまく行けばもっと長く続くでしょう。

一般的に、あまりにも多くのデータを共有する必要はないので、プロセスは非常に簡単です。


  • 見てみましょう。 OpenCLでは、コア数を指定する必要がありますか?すべてを「作業単位」に分割することを望んでいます。そのままにしておきます。 - mmr
  • まあ、あなたのアルゴリズムを任意の数のコアで動作するように開発してください。 - CookieOfFortune

1

Threading Building Blockもお勧めします。これをインテル®インテグレーテッド・パフォーマンス・プリミティブ私が働いている会社での画像解析のために。

Threading Building Block(TBB)はOpenMPとCilkの両方に似ています。そしてそれはマルチスレッド化をするためにOpenMPを使います、それは単により単純なインターフェースに包まれています。これで、スレッドをいくつ作成するかを気にする必要はなく、単にタスクを定義するだけです。可能であれば、タスクを分割してすべてをビジー状態に保ち、負荷分散を行います。

Intel Integrated Performance Primitives(Ipp)は、ビジョン用にライブラリを最適化しました。それらのほとんどはマルチスレッドです。私たちが必要とする機能については、IPPにはありませんが、TBBを使用してそれらをスレッド化します。

これらを使用して、画像を作成するためにIPP方法を使用するときに最良の結果が得られます。それがしていることは、与えられたキャッシュラインが完全に1つの行に含まれるように各行をパディングすることです。それでは、スレッドをまたがってイメージ内の行を分割することはしません。そのようにして、同じキャッシュラインに書き込もうとしている2つのスレッドから誤って共有することはありません。


  • 私はIPPには精通していますが、マルチスレッド/タイルコードはあまり役に立ちません(私の画像はすべて私たちの手によるものであり、uint8ではありません)。 TBBがこの問題を解決した場合、それはかなりエキサイティングです... - mmr
  • 私たちは、uint8と同様に私たちのイメージを使用しています。 TBBはどちらか一方と連携します。実際、私たちが自分で書いたほとんどの関数は両方の型を受け入れてTBBを使うテンプレートです。 - Ed_S
  • 明確にするために、IPPは異なるタイプのためのメモリアロケータを持っています。これらのアロケータは、すべてのキャッシュラインが完全に1つの行に含まれるようにします。これは、キャッシュ行が一杯になるように各行の終わりを埋めることによって行います。メモリを少し浪費しますが、幅1025 x高さ1024の画像では3%です。これは最悪の場合です。ほとんどの場合、あなたはより少ないメモリを無駄にするでしょう。 - Ed_S

0

Intelの(オープンソース)を見たことがありますかスレッディングビルディングブロック


  • 持っていません、チェックアウトします。 - mmr

0

まだ使っていませんが、シルク。彼らのチームの大きなかつらの1人はCharles E. Leisersonです。彼は "L"ですCLRS、地球上で最も広く/尊敬されて使用されているアルゴリズムの本。 私はそれがあなたの要求をうまく満たすと思います。

私の簡単な読みから、あなたがしなければならないのはあなたの「タグ」だけです既存のその後、自動的に/シームレスにコードを並列化します。これは彼らの大きなセールスポイントです。そのため、他のオプション(OpenMPなど)とは異なり、並列処理を念頭に置いて最初から始める必要はありません。


0

C、C ++、またはFortranのいずれかで既に実用的なシリアルコードをお持ちの場合は、OpenMPを十分に検討する必要があります。他の多くの並列化ライブラリ/言語/システムなどに比べて大きな利点の1つは、一度にループを並列化できることです。つまり、書き直すことなく、あるいはさらに悪いことには再実行することなく、高速化できます。 - デザイン、あなたのプログラム。

あなたの要求に関しては:

  1. OpenMPは高性能コンピューティングでよく使われており、その背後には多くの「重要性」と活発な開発コミュニティがあります - www.openmp.org。

  2. あなたがC、C ++またはFortranを選んだことが十分に運が良ければ、実装するのに十分な速さ。

  3. OpenMPは、並列コンピューティングに対する共有メモリアプローチを実装しているので、「ハードウェアを理解する必要がない」という議論に大きなプラスをもたらします。プログラムを実行して実行時にプロセッサがいくつあるかを把握してから、利用可能なものすべてに計算を分散させることもできます。

  4. あなたがすでに持っているハードウェア上で動きます、高価な、あるいは安い、追加のグラフィックスカードを必要としません。

  5. うん、Windowsシステム用の実装があります。

もちろん、最初にC、C ++、またはFortranを選択しないことが賢明でなかった場合、このアドバイスの多くは、それらの言語のいずれかに書き換えた後にのみ適用されます。

よろしく

マーク

リンクされた質問


関連する質問

最近の質問