web-dev-qa-db-ja.com

マルチコアプロセッサを使用するようにC ++アプリケーションを構築する方法

ビデオカメラフィードからオブジェクトトラッキングを実行し、そこからの情報を使用して OpenGL でパーティクルシステムを実行するアプリケーションを構築しています。ビデオフィードを処理するコードはやや遅く、現在フレームあたり200〜300ミリ秒です。これが実行されるシステムには、デュアルコアプロセッサが搭載されています。パフォーマンスを最大化するために、カメラの処理を1つのプロセッサにオフロードし、関連するデータを利用可能なときにメインアプリケーションに通信し、メインアプリケーションを他のプロセッサにキックしたままにします。

カメラワークを他のプロセッサにオフロードするために何をする必要があり、メインアプリケーションとの通信をどのように処理しますか?

編集:私はWindows 764ビットを実行しています。

14
Mr Bell

基本的に、アプリケーションをマルチスレッド化する必要があります。実行の各スレッドは、1つのコアのみを飽和させることができます。別々のスレッドは別々のコアで実行される傾向があります。各スレッドが常に特定のコアで実行されることを主張する場合、各オペレーティングシステムにはこれを指定する独自の方法(アフィニティマスクなど)があります...しかし、私はお勧めしません。

OpenMPは素晴らしいですが、特に並列化からバックアップに参加する場合は、お尻が少し太ります。 YMMV。使い方は簡単ですが、最高のパフォーマンスを発揮するオプションではありません。また、コンパイラのサポートも必要です。

Mac OS X 10.6(Snow Leopard)を使用している場合は、 Grand Central Dispatch を使用できます。その設計はいくつかのベストプラクティスを実装しているため、使用しなくても読むのは興味深いことです。また、最適ではありませんが、コンパイラのサポートも必要ですが、OpenMPよりも優れています。

アプリケーションを「タスク」または「ジョブ」に分割することに頭を悩ませることができれば、これらのジョブをコアと同じ数のパイプに押し込むことができます。処理をアトミックな作業単位としてバッチ処理することを考えてください。適切にセグメント化できれば、両方のコアとメインスレッドで同時にカメラ処理を実行できます。

作業単位ごとに通信が最小限に抑えられると、ミューテックスやその他のロックプリミティブの必要性が最小限に抑えられます。コースグレインスレッドは、ファイングレインよりもはるかに簡単です。また、いつでもライブラリやフレームワークを使用して負担を軽減できます。手動でアプローチする場合は、 ブーストのスレッドライブラリ を検討してください。ポータブルラッパーと素晴らしい抽象化を提供します。

12
pestilence669

それはあなたが持っているコアの数に依存します。コアが2つしかない場合(CPU、プロセッサ、ハイパースレッド、意味がわかります)、OpenMPはパフォーマンスを大幅に向上させることはできませんが、役立ちます。取得できる最大のゲインは、時間をプロセッサの数で割ることです。そのため、フレームあたり100〜150ミリ秒かかります。

方程式は
並列時間=(([タスクを実行する合計時間]-[並列化できないコード])/ [CPU数])+ [並列化できないコード]

基本的に、OpenMPは並列ループ処理で揺れ動きます。そのかなり使いやすい

#pragma omp parallel for
for (i = 0; i < N; i++)
    a[i] = 2 * i;

そして強打、あなたのforは並列化されます。すべての場合に機能するわけではありません。すべてのアルゴリズムをこの方法で並列化できるわけではありませんが、互換性を保つために多くのアルゴリズムを書き直す(ハッキングする)ことができます。重要な原則は、単一命令、複数データ(SIMD)であり、たとえば、同じ畳み込みコードを複数のピクセルに適用します。

しかし、このクックブックのレシピを適用するだけでは、最適化のルールに反します。
1-コードのベンチマーク
2-ボトルネックがあると思う場所を単純に推測するのではなく、「科学的」証拠(数値)を使用して実際のボトルネックを見つけます
3-実際にループを処理している場合は、OpenMPが最適です

たぶん、既存のコードを単純に最適化することで、より良い結果が得られるかもしれません。

別の道は、スレッドでopenglを実行し、別のスレッドでデータ処理を実行することです。これは、openglまたはパーティクルレンダリングシステムに多くの電力が必要な場合に大いに役立ちますが、スレッド化は他の種類の同期のボトルネックにつながる可能性があることに注意してください。

3
Eric

私はOpenMPに対してお勧めします。OpenMPは、あなたが持っているように見える消費者/生産者モデルではなく、数値コード用です。

ブーストスレッドを使用してワーカースレッドを生成し、メモリの共通セグメント(取得したデータの通信用)を使用して、データを通知する通知メカニズムを使用できる(ブーストスレッドの割り込みを調べる)ことで、簡単なことができると思います。

あなたがどのような処理をしているのかわかりませんが、IntelスレッドビルディングブロックとIntel統合プリミティブを見てみたいと思うかもしれません。それらはビデオ処理のためのいくつかの機能を持っています(あなたの機能があると仮定して)

2
Anycorn

マルチコアを処理するための何らかのフレームワークが必要です。 OpenMP はかなり単純な選択のようです。

1

Pestilenceが言ったように、アプリをマルチスレッド化する必要があります。 OpenMPのような多くのフレームワークが言及されているので、ここにもう1つあります。

インテルスレッドビルディングブロック

今まで使ったことがないのですが、いい話を聞いています。

お役に立てれば!

0
blwy10