3

新しいOpenCV2.4.3で、ユニバーサルparallel_forが追加されているのを見ました。したがって、このに従って、自分で実装しようとしました。すべてを自分のコードで機能させることができましたが、通常の「for」コマンドを使用して通常のシリアル方式で実行される同様のループと比較して処理のタイミングを調整すると、結果はわずかに速くなるか、多くの場合少し遅くなりました。

これは、ベクトルへのプッシュなどに関係しているのではないかと思ったので(並列処理にはかなり大きな初心者です)、大きな数を実行するだけのテストループを設定しましたが、それでも機能しません。

コード:

class Parallel_Test : public cv::ParallelLoopBody
{
private:
double* const mypointer;



public:
Parallel_Test(double* pointer)
: mypointer(pointer){

}
     void operator() (const Range& range) const
{
         //This constructor needs to be here otherwise it is considered an abstract class.
//             qDebug()<<"This should never be called";
}

    void operator ()(const cv::BlockedRange& range) const
    {

        for (int x = range.begin(); x < range.end(); ++x){

            mypointer[x]=x;

        }


    }



};


 //TODO Loop pixels in parallel
     double t = (double)getTickCount();

    //TEST PARALELL LOOPING AT ALL
    double data1[1000000];



        cv::parallel_for(BlockedRange(0, 1000000),  Parallel_Test(data1));

        t = ((double)getTickCount() - t)/getTickFrequency();
        qDebug() << "Parallel TEST time " << t << endl;


        t = (double)getTickCount();

        for(int i =0; i<1000000; i++){

            data1[i]=i;
        }
        t = ((double)getTickCount() - t)/getTickFrequency();
        qDebug() << "SERIAL Scan time " << t << endl;

出力:

Parallel TEST time  0.00415479 

SERIAL Scan time  0.00204597 
4

2 に答える 2

6

わお!答えが見つかりました!「parallel_for」と「parallel_for_」(末尾にアンダースコアが付いています!)はまったく異なります。それを機能させるには、末尾にアンダースコアが必要です。それ以外の場合は、ループをシリアルで実行するだけで、範囲の代わりにBLOCKEDRANGEを使用する必要があります。AHH!

これを指摘してくれた@DaniilOsokin、特に@Vladislav Vinogradovに感謝します!

したがって、コードは次のようになる必要があります。cv :: parallel_for_(Range(0、1000000)、Parallel_Test(data1));

詳細については、http://answers.opencv.org/question/3730/how-to-use-parallel_for/をご覧ください。

于 2012-12-13T15:47:32.953 に答える
3

問題は、ループ本体が小さすぎる可能性があります。

あなたがしているのは、あるベクトルのポインタを別のベクトルに割り当てることだけのようです。

並列forを非効率的なforループと考える必要があります。つまり、通常のデクリメントに加えて、比較するため、ループを展開してスピードアップすることを夢見ないように、各反復内の作業を十分に大きくする必要があります。それに進むことができるジャンプには、いくつかのインターロックされた命令と、おそらく仮想関数呼び出しまたは2つといくつかの割り当てがあります。

したがって、ポインタをコピーする代わりに、かなりの量の実際の計算を実行するか、大量のデータを処理してみてください。

于 2012-12-06T04:32:06.640 に答える