Tôi có một thuật toán đơn giản chuyển đổi kênh hình ảnh bộ đệm (BGGR, RGGB, GBRG, GRBG) thành rgb (demosaicing nhưng không có hàng xóm). Trong triển khai của tôi, tôi đã thiết lập sẵn các vectơ bù đắp giúp tôi dịch chỉ mục kênh bay đến các chỉ số kênh rgb tương ứng của nó. Chỉ có vấn đề là tôi đang nhận được hiệu suất khủng khiếp trong chế độ gỡ lỗi với MSVC11. Theo bản phát hành, cho đầu vào có kích thước 3264X2540, chức năng sẽ hoàn thành trong ~ 60ms. Đối với cùng một đầu vào trong gỡ lỗi, hàm hoàn thành trong ~ 20,000ms. Đó là sự khác biệt lớn hơn X300 và vì một số nhà phát triển đang chạy ứng dụng của tôi khi gỡ lỗi, điều đó không thể chấp nhận được.Sự khác biệt về hiệu năng mạnh mẽ: gỡ lỗi và phát hành
Mã của tôi:
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];
});
}
}
}
Những gì tôi đã cố gắng: tôi đã cố gắng Turing về tối ưu hóa (/ O2) cho debug xây dựng không có khác biệt đáng kể. Tôi đã thử thay thế câu lệnh bên trong for_each
bằng vòng lặp đơn giản là for
nhưng không có kết quả. Tôi có một thuật toán rất giống với thuật toán chuyển đổi bộ đệm sang rgb "xanh" (không sao chép dữ liệu sang các pixel lân cận trong khối) mà tôi không sử dụng std::vector
và có sự khác biệt thời gian chạy dự kiến giữa gỡ lỗi và phát hành (X2- X3). Vì vậy, có thể std::vector
là vấn đề? Nếu vậy, làm thế nào để vượt qua nó?
Tôi không hiểu. Có chuyện gì vậy? Nó hoàn toàn bình thường, được mong đợi và chấp nhận được, chế độ DEBUG sẽ chậm hơn đáng kể so với chế độ phát hành. Đó là lý do tại sao bạn có hai chế độ khác nhau. Chế độ gỡ lỗi chứa rất nhiều (thực sự rất nhiều) thông tin (siêu dữ liệu) cho mục đích gỡ lỗi. –
@KirilKirov Gỡ lỗi rất hữu ích, nhưng thường quá chậm để có thể sử dụng được. Đó chính là vấn đề. Vì vậy, bạn muốn kích hoạt nó một cách có chọn lọc, chỉ trên các thành phần quan tâm. Đó là giải pháp. –
@KirilKirov: Tôi mong đợi sự khác biệt về hiệu suất giữa gỡ lỗi và phát hành, nhưng tôi chưa bao giờ gặp phải sự khác biệt về hiệu suất của X300. Thuật toán của tôi là một lần lặp đơn đơn giản trên đầu vào. Tôi đã mong đợi một sự khác biệt hợp lý trong thời gian – eladidan