2010-05-26 19 views
5

में अजीब प्रदर्शन मेरे पास सी ++ में लिखा गया यह लूप है, जिसे MSVC2010 के साथ संकलित करने में काफी समय लगता है। (300 मि.से)सी ++ (वीसी 2010)

for (int i=0; i<h; i++) { 
    for (int j=0; j<w; j++) { 
     if (buf[i*w+j] > 0) { 
      const int sy = max(0, i - hr); 
      const int ey = min(h, i + hr + 1); 
      const int sx = max(0, j - hr); 
      const int ex = min(w, j + hr + 1); 
      float val = 0; 
      for (int k=sy; k < ey; k++) { 
       for (int m=sx; m < ex; m++) { 
        val += original[k*w + m] * ds[k - i + hr][m - j + hr]; 
       } 
      } 
      heat_map[i*w + j] = val; 
     } 
    } 
} 

यह मेरे लिए थोड़ा अजीब लग रहा था, इसलिए मैं कुछ परीक्षण तो विधानसभा इनलाइन करने के लिए कुछ बिट्स बदल दिया: (विशेष रूप से, कोड है कि योग "वैल")

for (int i=0; i<h; i++) { 
    for (int j=0; j<w; j++) { 
     if (buf[i*w+j] > 0) { 
      const int sy = max(0, i - hr); 
      const int ey = min(h, i + hr + 1); 
      const int sx = max(0, j - hr); 
      const int ex = min(w, j + hr + 1); 
      __asm { 
       fldz 
      } 
      for (int k=sy; k < ey; k++) { 
       for (int m=sx; m < ex; m++) { 
        float val = original[k*w + m] * ds[k - i + hr][m - j + hr]; 
        __asm { 
         fld val 
         fadd 
        } 
       } 
      } 
      float val1; 
      __asm { 
       fstp val1 
      } 
      heat_map[i*w + j] = val1; 
     } 
    } 
} 

अब यह आधा समय, 150 एमएमएस में चलता है। यह बिल्कुल वही काम करता है, लेकिन यह दो बार जल्दी क्यों है? दोनों स्थितियों में इसे रिलीज मोड में ऑप्टिमाइज़ेशन के साथ चलाया गया था। क्या मैं अपने मूल सी ++ कोड में कुछ गलत कर रहा हूं?

+3

क्या आपने दोनों मामलों में जेनरेट किए गए असेंबली कोड की तुलना करने का प्रयास किया था ... –

उत्तर

5

मैं सुझाव है कि आप अलग अलग फ्लोटिंग प्वाइंट गणना संकलक द्वारा समर्थित मॉडल की कोशिश - किसी भी निष्कर्ष करने से पहले अपने मूल कोड के साथ - precise, strict या fast (देखें /fp विकल्प)। मुझे संदेह है कि आपका मूल कोड कुछ अत्यधिक प्रतिबंधित फ्लोटिंग-पॉइंट मॉडल (कोड के दूसरे संस्करण में आपकी असेंबली के बाद नहीं) के साथ संकलित किया गया था, यही कारण है कि मूल बहुत धीमा है।

दूसरे शब्दों में, यदि मूल मॉडल वास्तव में बहुत ही सीमित था, तो आप बस संतरे से सेब की तुलना कर रहे थे। दो संस्करण वास्तव में एक ही काम नहीं करते थे, भले ही यह पहली नजर में ऐसा प्रतीत हो।

नोट, उदाहरण के लिए, कोड के पहले संस्करण में इंटरमीडिएट योग float मान में जमा होता है। यदि इसे precise मॉडल के साथ संकलित किया गया था, तो इंटरमीडिएट परिणामों को float प्रकार की सटीकता के लिए गोल करना होगा, भले ही परिवर्तनीय val को अनुकूलित किया गया हो और आंतरिक एफपीयू रजिस्टर का उपयोग किया गया हो। आपके असेंबली कोड में आप संचित परिणाम को गोल करने के लिए परेशान नहीं हैं, जो इसके बेहतर प्रदर्शन में योगदान दे सकता है।

मेरा सुझाव है कि आप कोड के दोनों संस्करणों को /fp:fast मोड में संकलित करें और देखें कि उनके प्रदर्शन की तुलना उस मामले में कैसे की जाती है।

+0

धन्यवाद!मैंने फास्ट मोड में अपना मूल कोड चलाया है और अब यह 80ms में चलता है, जबकि दूसरा संस्करण अभी भी फास्ट मोड में 150 एमएमएस पर चलता है, इसलिए मुझे लगता है कि कंपाइलर अभी भी बेहतर जानता है :) मुझे इन # प्रागमा को एमएसवीसी के लिए मिला है समारोह प्रति नाव परिशुद्धता टॉगल करने के लिए (अंदर कार्यों काम नहीं करता है): #pragma float_control (सटीक, बंद, पुश) ... यहाँ कोड ... #pragma float_control (पॉप) लेकिन अधिक विशेष रूप से: http://msdn.microsoft.com/en-us/library/45ec64h6(VS.80).aspx – raicuandi

3

कुछ बाहर की जाँच करने के लिए बातें:

  • आपको लगता है कि वास्तव में एक ही कोड है की जाँच की जरूरत है। जैसा कि, आपके इनलाइन असेंबली स्टेटमेंट्स वास्तव में संकलक द्वारा उत्पन्न किए गए समान हैं? मैं तीन संभावित मतभेद देख सकता हूं (संभावित क्योंकि उन्हें अनुकूलित किया जा सकता है)। पहला val की प्रारंभिक सेटिंग शून्य है, दूसरा अतिरिक्त चर val1 है (संभावना है क्योंकि यह केवल स्टैक पॉइंटर के निरंतर घटाव को बदल देगा), तीसरा यह है कि आपका इनलाइन असेंबली संस्करण अंतरिम परिणाम नहीं डाल सकता है val में वापस।

  • आपको यह सुनिश्चित करना होगा कि आपका नमूना स्थान बड़ा है। आपने यह उल्लेख नहीं किया कि आपने प्रत्येक संस्करण के केवल एक रन या सौ रन बनाए हैं, लेकिन आपके आंकड़ों में "शोर" के प्रभाव को दूर करने के लिए जितना अधिक रन उतना बेहतर होगा।

  • एक बेहतर माप भी समय के बजाय CPU समय होगा। विलुप्त समय पर्यावरण परिवर्तनों के अधीन है (जैसे आपका वायरस चेकर या आपकी सेवाओं में से एक जब आप परीक्षण कर रहे हैं तो कुछ करने का निर्णय लेते हैं)। बड़ी नमूना जगह कम हो जाएगी, लेकिन यह जरूरी नहीं है, यह।

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