2013-04-11 5 views
5

저는 베이어 이미지 채널 (BGGR, RGGB, GBRG, GRBG)을 rgb (디 모사 싱하지만 이웃하지 않고)로 변환하는 간단한 알고리즘을 가지고 있습니다. 구현시 바이엘 채널 인덱스를 해당 rgb 채널 인덱스로 변환하는 데 도움이되는 오프셋 벡터를 미리 설정했습니다. 문제는 MSVC11로 디버그 모드에서 끔찍한 성능을 얻고 있습니다. 릴리스에서 3264X2540 크기의 입력에 대해 함수는 ~ 60ms 이내에 완료됩니다. 디버그의 동일한 입력에 대해 함수는 ~ 20,000ms 내로 완료됩니다. 그것은 X300 이상의 차이점이며 일부 개발자는 내 응용 프로그램을 디버그로 실행하기 때문에 용납 할 수 없습니다.두드러진 성능 차이 : 디버그 대 릴리스

내 코드 : 내가 디버그 유의 한 차이 구축에 대한 최적화에 튜링 (/ O2)를 시도 :

나는 무엇을 시도했다
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]; 
       }); 
     } 
    } 
} 

. 내부의 for_each 문을 보통의 이전 for 루프로 바꾸려고했지만 아무 소용이 없습니다. 나는 블록을 이웃하는 픽셀에 복사하지 않고 "녹색"rgb로 바꾼 매우 비슷한 알고리즘을 가지고있다. 어느 곳에서 나는 std::vector을 사용하지 않고 거기에 디버그와 릴리즈 사이에 예상되는 런타임 차이가있다. (X2- X3). 그래서, std::vector은 문제가 될 수 있습니까? 그렇다면 어떻게 극복 할 수 있습니까?

+5

나는 그것을 얻지 못한다. 뭐가 문제 야? DEBUG 모드가 릴리즈 모드보다 상당히 느릴 것이라는 것은 완벽하고 정상적이고 예상 가능합니다. 그래서 두 가지 모드가 있습니다. 디버그 모드에는 디버깅 목적으로 많은 정보 (메타 데이터)가 포함되어 있습니다. –

+1

@KirilKirov 디버그는 유용하지만 사용하기에는 너무 느린 경우가 종종 있습니다. 그것이 문제이다. 따라서 관심있는 구성 요소에서만 선택적으로 활성화하려고합니다. 그것이 해결책입니다. –

+0

@KirilKirov : 디버그와 릴리스 간의 성능 차이가 예상되지만 X300 성능 차이가 발생하지 않았습니다. 내 알고리즘은 입력에 대한 단순한 단일 반복입니다. 나는 합리적인 차이를 기대했다. – eladidan

답변

14

std::vector을 사용하면 반복기 디버깅을 비활성화하는 데 도움이됩니다. 당신이 어떤 STL 헤더를 포함하기 전에

간단한 측면에서

MSDN shows how to do it.

#define을 : 내 경험에

#define _HAS_ITERATOR_DEBUGGING 0 

을,이 물론 있지만, 디버그 빌드의 성능 주요 향상을 제공 일부 디버깅 기능을 잃게됩니다.

+0

+1. 나는 이것이 차이, 좋은 대답의 주된 원인이라고 생각한다. –

+0

@MatsPetersson 특히 C++과 STL의 "아름다움"입니다. 프로그램의 한 줄이 꽤 많은 것을 숨길 수 있습니다. 그 때 물건은 매우 비쌉니다. –

+0

니스, 그게 좋겠다고 생각했지만 도움이되지 않았다 ... 다른 어떤 생각? – eladidan

0

VS에서는 디버깅을 위해 아래 설정을 사용할 수 있습니다 (/ Od). 다른 옵션 (최소 크기 (/ O1), 최대 속도 (/ O2), 전체 최적화 (/ Ox) 또는 사용자 지정) 중 하나를 선택하십시오. Roger Rowland가 말한 반복자 최적화와 함께 ...

+0

필자의 글에서 언급했듯이/O2를 사용해 보았지만 큰 차이는 없었다. – eladidan

관련 문제