저는 베이어 이미지 채널 (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
은 문제가 될 수 있습니까? 그렇다면 어떻게 극복 할 수 있습니까?
나는 그것을 얻지 못한다. 뭐가 문제 야? DEBUG 모드가 릴리즈 모드보다 상당히 느릴 것이라는 것은 완벽하고 정상적이고 예상 가능합니다. 그래서 두 가지 모드가 있습니다. 디버그 모드에는 디버깅 목적으로 많은 정보 (메타 데이터)가 포함되어 있습니다. –
@KirilKirov 디버그는 유용하지만 사용하기에는 너무 느린 경우가 종종 있습니다. 그것이 문제이다. 따라서 관심있는 구성 요소에서만 선택적으로 활성화하려고합니다. 그것이 해결책입니다. –
@KirilKirov : 디버그와 릴리스 간의 성능 차이가 예상되지만 X300 성능 차이가 발생하지 않았습니다. 내 알고리즘은 입력에 대한 단순한 단일 반복입니다. 나는 합리적인 차이를 기대했다. – eladidan