2013-04-11 17 views
5

Bayer görüntü kanalını (BGGR, RGGB, GBRG, GRBG) rgb'ye dönüştüren basit bir algoritmam var (öykünme ancak komşu olmadan). Uygulamamda, bayer kanal indeksini karşılık gelen rgb kanal indislerine çevirmeme yardımcı olan önceden ayarlanmış ofset vektörlerine sahibim. Sadece sorun MSVC11 ile hata ayıklama modunda korkunç bir performans alıyorum. Serbest bırakıldığında, 3264X2540 boyutundaki bir giriş için işlev ~ 60 ms'de tamamlanır. Hata ayıklamasında aynı girdi için, işlev ~ 20.000 ms'de tamamlanır. Bu, X300 farkından daha fazla ve bazı geliştiriciler uygulamada hata ayıklama olduğundan, kabul edilemez.Ağır performans farklılıkları: debug vs release

Kodum: Ben Hata ayıklamak anlamlı farklar ile inşa için optimizasyon üzerinde turing (/ O2) denedik :

denedim ne
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 ifadesini eski bir for döngüsüyle değiştirmeyi denedim, ancak boşuna. Bayer'i "yeşil" rgb'ye dönüştüren (bloğu komşu piksellere veri kopyalamadan) std::vector kullanmıyorum ve hata ayıklaması ile serbest bırakma arasında beklenen çalışma zamanı farkı var. (X2- X3). Yani, std::vector sorun olabilir mi? Eğer öyleyse, nasıl üstesinden gelebilirim?

+5

Anlamadım. Sorun ne? Tamamen normal, beklenen ve kabul edilebilir, DEBUG modu, serbest bırakma modundan önemli ölçüde daha yavaş olacaktır. Bu yüzden iki farklı modun var. Hata ayıklama modu, hata ayıklama amaçları için çok (gerçekten çok) bilgi (meta veri) içerir. –

+1

@KirilKirov Hata ayıklama yararlıdır, ancak çoğu zaman kullanılabilecek kadar yavaştır. İşte sorun bu. Bu yüzden onu seçici olarak, sadece ilgili bileşenlerde etkinleştirmek istiyorsunuz. Bu çözüm. –

+0

@KirilKirov: Debug ile sürüm arasındaki performans farklılıklarını bekliyorum, ancak X300 performans farklılıklarıyla hiç karşılaşmadım. Algoritimlerim, giriş üzerinde basit bir tek yineleme. Gördüğüm – eladidan

cevap

14

std::vector'u kullanırken, yineleyici hata ayıklamasını devre dışı bırakmanıza yardımcı olur. Eğer herhangi bir STL başlıklarını içerir önce

Basit bir ifadeyle

MSDN shows how to do it.

, bu #define olun: Tecrübelerime göre

#define _HAS_ITERATOR_DEBUGGING 0 

, bu tabii ki her ne kadar, inşa Debug performansında bir büyük destek veriyor bazı hata ayıklama işlevlerini kaybedersiniz.

+0

+1. Bunun farkın ana sebebi olduğuna inanıyorum, iyi cevap. –

+0

@MatsPetersson Bu özellikle C++ ve STL'nin "güzelliği" dir. Programınızdaki tek bir satır çok fazla şey gizliyor olabilir. Bazen bu şeyler çok maliyetli. –

+0

Güzel, Bunun olacağından emindim ama başka hiçbir fikre yardım etmedi mi? – eladidan

0

VS'de, hata ayıklama, Devre Dışı (/ Od) için aşağıdaki ayarları kullanabilirsiniz. Diğer seçeneklerden birini seçin (Minimum Boyut (/ O1), Maksimum Hız (/ O2), Tam Optimizasyon (/ Ox) veya Özel). Roger Rowland'ın bahsettiği yineleyici optimizasyonu ile birlikte ...

+0

Yazımda belirttiğim gibi,/O2 kullanmayı denedim ama hiçbir önemli fark olmadan – eladidan

İlgili konular