2013-04-11 15 views
5

Ho un semplice algoritmo che converte un canale di immagine bayer (BGGR, RGGB, GBRG, GRBG) in rgb (demosaicing ma senza vicini). Nella mia implementazione ho preimpostato i vettori offset che mi aiutano a tradurre l'indice del canale bayer nei corrispondenti indici dei canali rgb. L'unico problema è che sto ottenendo prestazioni terribili in modalità di debug con MSVC11. Sotto release, per un input della dimensione 3264X2540 la funzione termina in ~ 60ms. Per lo stesso input in debug, la funzione termina in ~ 20.000ms. Questo è più della differenza X300 e dal momento che alcuni sviluppatori eseguono la mia applicazione in debug, è inaccettabile.Differenze di prestazioni drastiche: debug vs release

Il mio codice:

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]; 
       }); 
     } 
    } 
} 

Quello che ho provato: ho provato Turing sull'ottimizzazione (/ O2) per la generazione di debug senza differenze significative. Ho provato a sostituire l'istruzione interna for_each con un semplice ciclo vecchio for ma senza risultato. Ho un algoritmo molto simile che converte bayer in "verde" rgb (senza copiare i dati in pixel vicini nel blocco) in cui non sto usando il std::vector e lì c'è la differenza di runtime attesa tra debug e release (X2- X3). Quindi, potrebbe il std::vector essere il problema? Se sì, come posso superarlo?

+5

Non capisco. Qual è il problema? È perfettamente normale, previsto e accettabile, che la modalità DEBUG sia notevolmente più lenta della modalità di rilascio. Ecco perché hai due diverse modalità. La modalità debug contiene molte (davvero molte) informazioni (metadati) a scopo di debug. –

+1

@KirilKirov Il debug è utile, ma spesso è troppo lento per essere utilizzabile. Questo è il problema. Quindi vuoi attivarlo in modo selettivo, solo sui componenti di interesse. Questa è la soluzione. –

+0

@KirilKirov: mi aspetto differenze di prestazioni tra debug e release, ma non ho mai riscontrato differenze di prestazioni X300. I miei algoritmi sono una semplice singola iterazione sull'input. Mi aspettavo una differenza ragionevole nei tempi – eladidan

risposta

14

Poiché si utilizza std::vector, sarà utile disabilitare il debug degli iteratori.

MSDN shows how to do it.

In termini semplici, fanno di questo #define prima di includere le intestazioni STL:

#define _HAS_ITERATOR_DEBUGGING 0 

Nella mia esperienza, questo dà un grande spinta in termini di prestazioni di build di debug, anche se naturalmente si perde alcune funzionalità di debug.

+0

+1. Credo che questa sia la principale causa di differenza, buona risposta. –

+0

@MatsPetersson Questa è la "bellezza" di C++ e STL in particolare. Una singola riga del tuo programma potrebbe nascondere un sacco di cose. A volte quella roba è molto costosa. –

+0

Bello, ero sicuro che sarebbe stato ma non ha aiutato ... qualche altra idea? – eladidan

0

In VS è possibile utilizzare le seguenti impostazioni per il debug, Disabilitato (/ Od). Scegliere una delle altre opzioni (Dimensione minima (/ O1), Velocità massima (/ O2), Ottimizzazione completa (/ Ox) o Personalizzata). Insieme all'ottimizzazione dell'iteratore che Roger Rowland ha menzionato ...

+0

Come ho menzionato nel mio post, ho provato a usare/O2 ma senza differenze significative – eladidan

Problemi correlati