2013-04-11 1 views
5

मेरे पास एक साधारण एल्गोरिदम है जो एक बेयर छवि चैनल (बीजीजीआर, आरजीबीबी, जीबीआरजी, जीआरबीजी) को आरजीबी (डेमोसाइजिंग लेकिन पड़ोसियों के बिना) में परिवर्तित करता है। मेरे कार्यान्वयन में मैंने प्री-सेट ऑफ़सेट वेक्टर हैं जो मुझे बैयर चैनल इंडेक्स को इसके संबंधित आरजीबी चैनल इंडेक्स में अनुवाद करने में मदद करते हैं। केवल समस्या यह है कि मुझे MSVC11 के साथ डीबग मोड में भयानक प्रदर्शन मिल रहा है। रिलीज के तहत, 3264X2540 आकार के इनपुट के लिए फ़ंक्शन ~ 60ms में पूरा हो जाता है। डीबग में एक ही इनपुट के लिए, फ़ंक्शन ~ 20,000ms में पूरा हो जाता है। यह X300 अंतर से अधिक है और चूंकि कुछ डेवलपर डीबग में मेरे एप्लिकेशन को चला रहे हैं, यह अस्वीकार्य है।कठोर प्रदर्शन अंतर: डीबग बनाम रिलीज

मेरे कोड:

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

मैं क्या कोशिश की है: मैं डिबग कोई महत्वपूर्ण मतभेद के साथ निर्माण के लिए अनुकूलन पर ट्यूरिंग (/ O2) की कोशिश की। मैंने आंतरिक for_each कथन को एक सादे पुराने for लूप के साथ बदलने की कोशिश की लेकिन इसका कोई फायदा नहीं हुआ। मेरे पास एक बहुत ही समान एल्गोरिदम है जो बैयर को "हरा" आरजीबी (ब्लॉक में पड़ोसी पिक्सेल में डेटा कॉपी किए बिना) में परिवर्तित करता है जिसमें मैं std::vector का उपयोग नहीं कर रहा हूं और वहां डीबग और रिलीज के बीच अपेक्षित रनटाइम अंतर है (एक्स 2- X3)। तो, std::vector समस्या हो सकती है? यदि हां, तो मैं इसे कैसे दूर करूं?

+5

मुझे यह नहीं मिला। समस्या क्या है? यह पूरी तरह से सामान्य, अपेक्षित और स्वीकार्य है, कि डीईबीयूजी मोड रिलीज मोड की तुलना में काफी धीमी होगी। यही कारण है कि आपके पास दो अलग-अलग तरीके हैं। डीबग मोड में डीबगिंग उद्देश्यों के लिए बहुत कुछ (वास्तव में बहुत) जानकारी (मेटा डेटा) है। –

+1

@ किरिलकिरोव डीबग उपयोगी है, लेकिन अक्सर उपयोग करने योग्य होने में बहुत धीमी होती है। यही समस्या है। तो आप इसे केवल रुचि के घटकों पर चुनिंदा रूप से सक्षम करना चाहते हैं। यही समाधान है। –

+0

@ किरिलकिरोव: मुझे डीबग और रिलीज के बीच प्रदर्शन अंतर की उम्मीद है, लेकिन मुझे कभी भी X300 प्रदर्शन अंतर का सामना नहीं हुआ है। मेरा एल्गोरिदम इनपुट पर एक साधारण एकल पुनरावृत्ति है। मुझे लगता है कि – eladidan

उत्तर

14

जैसा कि आप std::vector का उपयोग करते हैं, यह इटेटरेटर डिबगिंग को अक्षम करने में मदद करेगा। इससे पहले कि आप किसी भी एसटीएल हेडर शामिल हैं

MSDN shows how to do it.

सरल शब्दों में, इस #define बनाने:

#define _HAS_ITERATOR_DEBUGGING 0 

मेरे अनुभव में, यह बनाता है डिबग के प्रदर्शन में प्रमुख बढ़ावा देता है, निश्चित रूप से, हालांकि आप कुछ डिबगिंग कार्यक्षमता खो देते हैं।

+0

+1। मेरा मानना ​​है कि यह अंतर का मुख्य कारण है, अच्छा जवाब है। –

+0

@ मैट्स पीटरसन यह विशेष रूप से सी ++ और एसटीएल की "सुंदरता" है। आपके कार्यक्रम में एक पंक्ति बहुत सारी चीजें छुपा रही है। कभी-कभी सामान बहुत महंगा होता है। –

+0

अच्छा, मुझे यकीन था कि यह होगा लेकिन यह मदद नहीं की ... कोई अन्य विचार? – eladidan

0

वीएस में आप डीबगिंग, अक्षम (/ ओडी) के लिए नीचे सेटिंग्स का उपयोग कर सकते हैं। अन्य विकल्पों में से एक चुनें (न्यूनतम आकार (/ ओ 1), अधिकतम गति (/ ओ 2), पूर्ण अनुकूलन (/ ऑक्स), या कस्टम)। रोजर रोवलैंड ने इटरेटर ऑप्टिमाइज़ेशन के साथ ...

+0

जैसा कि मैंने अपनी पोस्ट में उल्लेख किया है, मैंने/O2 का उपयोग करने की कोशिश की लेकिन बिना किसी महत्वपूर्ण अंतर के – eladidan

संबंधित मुद्दे