2013-04-11 15 views
5

私は、ベイヤーイメージチャネル(BGGR、RGGB、GBRG、GRBG)をrgb(デモザイクしているがネイバーがない)に変換する単純なアルゴリズムを持っています。私の実装では、ベイヤーチャンネルインデックスを対応するrgbチャンネルインデックスに変換するのに役立つオフセットベクトルをあらかじめ設定しています。 私はMSVC11でデバッグモードでひどい性能を得ているだけです。リリース時には、3264X2540サイズの入力に対して、関数は約60msで完了します。デバッグ時の同じ入力に対して、関数は〜20,000msで完了します。これはX300の違い以上のもので、一部の開発者がデバッグで自分のアプリケーションを実行しているため、受け入れられません。劇的なパフォーマンスの違い:debug vs release

マイコード:

私が試した何
void ConvertBayerToRgbImageDemosaic(int* BayerChannel, int* RgbChannel, int Width, int 

Height, ColorSpace ColorSpace) 
{ 
    int rgbOffsets[4]; //translates color location in Bayer block to it's location in RGB block. So R->0, G->1, B->2 
    std::vector<int> bayerToRgbOffsets[4]; //the offsets from every color in the Bayer block to (bayer) indices it will be copied to (R,B are copied to all indices, Gr to R and Gb to B). 
    //calculate offsets according to color space 
    switch (ColorSpace) 
    { 
    case ColorSpace::BGGR: 
      /* 
      B G 
      G R 
      */ 
     rgbOffsets[0] = 2; //B->0 
     rgbOffsets[1] = 1; //G->1 
     rgbOffsets[2] = 1; //G->1 
     rgbOffsets[3] = 0; //R->0 
     //B is copied to every pixel in it's block 
     bayerToRgbOffsets[0].push_back(0); 
     bayerToRgbOffsets[0].push_back(1); 
     bayerToRgbOffsets[0].push_back(Width); 
     bayerToRgbOffsets[0].push_back(Width + 1); 
     //Gb is copied to it's neighbouring B 
     bayerToRgbOffsets[1].push_back(-1); 
     bayerToRgbOffsets[1].push_back(0); 
     //GR is copied to it's neighbouring R 
     bayerToRgbOffsets[2].push_back(0); 
     bayerToRgbOffsets[2].push_back(1); 
     //R is copied to every pixel in it's block 
     bayerToRgbOffsets[3].push_back(-Width - 1); 
     bayerToRgbOffsets[3].push_back(-Width); 
     bayerToRgbOffsets[3].push_back(-1); 
     bayerToRgbOffsets[3].push_back(0); 
     break; 
    ... other color spaces 
    } 

    for (auto row = 0; row < Height; row++) 
    { 
     for (auto col = 0, bayerIndex = row * Width; col < Width; col++, bayerIndex++) 
     { 
      auto colorIndex = (row%2)*2 + (col%2); //0...3, For example in BGGR: 0->B, 1->Gb, 2->Gr, 3->R 
      //iteration over bayerToRgbOffsets is O(1) since it is either sized 2 or 4. 
      std::for_each(bayerToRgbOffsets[colorIndex].begin(), bayerToRgbOffsets[colorIndex].end(), 
       [&](int colorOffset) 
       { 
        auto rgbIndex = (bayerIndex + colorOffset) * 3 + rgbOffsets[offset]; 
        RgbChannel[rgbIndex] = BayerChannel[bayerIndex]; 
       }); 
     } 
    } 
} 

: を私は有意差とデバッグビルドの(/ O2)最適化にチューリングみました。 内部のfor_eachステートメントを普通の古いforループに置き換えようとしましたが、役に立たなくなりました。私はstd::vectorを使用していないで、ベイヤーを "緑色"のrgb(ブロック内の隣接するピクセルにデータをコピーしないで)に変換する非常に似たアルゴリズムを持っており、そこにはデバッグとリリース(X2- X3)。だから、std::vectorは問題になる可能性がありますか?もしそうなら、私はそれをどのように克服するのですか?

+5

私はそれを得ていません。どうしたの? DEBUGモードがリリースモードよりも大幅に遅くなることは、完全に正常であり、予想され、受け入れられます。だからあなたは2つの異なるモードを持っています。デバッグモードには、デバッグの目的でたくさんの情報(メタデータ)が含まれています。 –

+1

@KirilKirov Debugは便利ですが、使用するには遅すぎることがよくあります。それが問題です。だから、関心のあるコンポーネントだけを選択的に有効にしたい。それが解決策です。 –

+0

@KirilKirov:デバッグとリリースのパフォーマンスの違いがあると思いますが、X300のパフォーマンスの違いは一度もありません。私のアルゴリズムは入力に対する単純な1回の反復です。私は時間の合理的な違いを期待していた – eladidan

答えて

14

std::vectorを使用しているので、イテレータのデバッグを無効にするのに役立ちます。簡単に言えば

MSDN shows how to do it.

、あなたはどのSTLヘッダを含める前にこの#defineを行います。私の経験で

#define _HAS_ITERATOR_DEBUGGING 0 

を、これは、デバッグのパフォーマンスの主要ブーストはもちろんのが、ビルドを提供しますいくつかのデバッグ機能が失われます。

+0

+1。私はこれが違い、良い答えの主な原因だと信じています。 –

+0

@MatsPeterssonそれは特にC++とSTLの "美しさ"です。あなたのプログラムの1行はかなり多くのものを隠しているかもしれません。その時には非常に高価です。 –

+0

ニース、それはそれだと確信していましたが、それは助けになりません...他のアイデア? – eladidan

0

VSでは、デバッグにDisabled(/ Od)を使用できます。他のオプション(最小サイズ(/ O1)、最大速度(/ O2)、完全最適化(/ Ox)、カスタム)のいずれかを選択します。 Roger Rowlandが述べたイテレータの最適化に加えて...

+0

私の記事で触れたように、私は/ O2を使ってみましたが、大きな違いはありませんでした – eladidan

関連する問題