0

CreateMutex() について質問があります

私は画像データに取り組んでおり、画像のさまざまな回転に対して特定の計算を行っています。画像を 180 段階 (1° 段階) で回転させます。これらは結果を書き戻す以外は互いに独立しているため、これをマルチスレッド化することにしました (非常に集中的な計算であり、メモリへの書き込みに時間がかかりません)。実行の)。

最初は、スレッドが書き込みまたは書き込みを行わないようにする単一のミューテックスを使用してみましたが、パフォーマンスが大幅に低下しました (ミューテックスなしの単一スレッドで 100% の時間から約 80% の実行速度になりました)。

次に、ピクセルごとに 1 つの HANDLE の配列を作成しました (656x480 であるため、ハンドル数は約 300k です)。これにより、コードの実行時間が約 15% (同時に 7 つのスレッド) に改善されました。

これをタスク マネージャーで見ると、Handles という独自のカテゴリがあることがわかります。これは 30k の間 (一部のプログラムと OS が実行されている場合) で、コードを実行すると 350k になります。

この振る舞いは大丈夫ですか、それとも悪いので変更する必要がありますか? もしそうなら、なぜ、どのように?

4

2 に答える 2

3

350k 以上のハンドルを使用する単一のプロセスは多すぎると言えます。(1 ピクセルあたり 1 つのハンドル、本当に?)

複数のスレッドを使用してアプリケーションの全体的な効率を向上させたい場合は、これらのスレッド間の競合の量を減らすことをお勧めします。あなたのアプリケーションが何をしているのかよくわかりませんが、単一のソース イメージの 180 の異なるローテーションを作成している場合は、ソース イメージの N 個のコピーを作成することを検討してください (N は実行するスレッドの数です)。 、および各スレッドがソース イメージの独自のコピーで動作するようにします。そうすれば、ミューテックスをまったく持つ必要がなくなり、スレッド間の競合が減ります。

于 2012-07-30T23:07:56.627 に答える
0

CRITICAL_SECTIONミューテックスではなく、を使用する必要があります。彼らははるかに高速です。で初期化すると、スピンロックのような動作を得ることができますInitializeCriticalSectionAndSpinCount()

他の人が言ったように、すべてのピクセルにミューテックスを持つのは正気ではありません。スレッドはいくつありますか?

ロックをまったく必要としないはずであり、これらすべてのスレッドを自分で作成する代わりに、OpenMP と並行してイメージを処理できます。OpenMP の特徴は、出力画像の各行に 1 つの並列化された外部ループを配置し、その内部でその行の各ピクセルを調べることができることです。これで、出力は独立しています。

回転を行うには、その出力ピクセルの位置から逆回転のピクセル位置を見つけ、その位置でカラー値をエリア サンプリングします。特に、各画像に対して 1 つの sin と cos の計算を行うだけでよいため (角度はすべてのピクセルで変化しません)、これはまったく計算集約的ではありません。

つまり、要約すると...ワーカースレッド、ミューテックス、sin / cosへの冗長な呼び出しはありません。コードの完成までの速さに驚かれることでしょう。

double sintheta = sin(theta);
double costheta = cos(theta);

#pragma omp parallel for 
for( int y = 0; y < height; y++ ) {
    RGB * inputRow = &inputImage[y * width];
    RGB * outputRow = &outputImage[y * width];

    for( int x = 0; x < width; x++ ) {
        // Whatever your rotation code should be.... =)
        double rotx = -((double)x - xCentre) * costheta;
        double roty = -((double)y - yCentre) * sintheta;

        // Interpolate colour from input image.  We've landed inside
        // a 2x2 square of pixels.  Take some of each.  I'll leave the
        // sampling to you...
        RGB val;
        // TODO

        // Output the rotated pixel without thread contention.
        outputRow[x] = val;
    }
}
于 2012-07-31T02:46:57.743 に答える