2012-01-25 10 views
8

मेरे पास निम्नलिखित C++ कोड स्निपेट है (सी ++ भाग प्रोफाइलर क्लास है जो यहां छोड़ा गया है), वीएस -2010 (64 बिट इंटेल मशीन) के साथ संकलित। कोड बस एक अदिश के साथ तैरता (arr2) की एक सरणी गुणा करता है, और एक अन्य सरणी (arr1) में परिणाम कहते हैं:प्रदर्शन अंतर्निहित डेटा मानों पर निर्भर करता है

int M = 150, N = 150; 
int niter = 20000; // do many iterations to have a significant run-time 
float *arr1 = (float *)calloc (M*N, sizeof(float)); 
float *arr2 = (float *)calloc (M*N, sizeof(float)); 

// Read data from file into arr2 

float scale = float(6.6e-14); 

// START_PROFILING 
for (int iter = 0; iter < niter; ++iter) { 
    for (int n = 0; n < M*N; ++n) {   
     arr1[n] += scale * arr2[n]; 
    } 
} 
// END_PROFILING 

free(arr1); 
free(arr2); 

पढ़ने-से-फ़ाइल हिस्सा है और रूपरेखा (यानी रन-टाइम माप) है सादगी के लिए यहां छोड़ा गया।

जब arr2 रेंज में यादृच्छिक संख्या को आरंभ नहीं हो जाता [0 1], कोड तेजी के रूप में एक मामले में जहां arr2 एक विरल सरणी जिसमें मूल्यों के बारे में 2/3 शून्य कर रहे हैं करने के लिए आरंभ नहीं हो जाता की तुलना के बारे में 10 बार चलाता है । मैंने कंपाइलर विकल्प /fp और /O के साथ खेला है, जिसने रन-टाइम को थोड़ा सा बदल दिया है, लेकिन 1:10 का अनुपात लगभग रखा गया था।

  • प्रदर्शन वास्तविक मूल्यों पर निर्भर कैसे होता है? सीपीयू अलग-अलग करता है जो स्पैस डेटा को ~ 10 गुना धीमा कर देता है?
  • क्या "धीमी डेटा" तेजी से चलाने के लिए कोई तरीका है, या कोई ऑप्टिमाइज़ेशन (उदाहरण के लिए गणना को सदिश बनाना) दोनों सरणी पर समान प्रभाव डालता है (यानी, "धीमी डेटा" अभी भी धीमी गति से चलती है तो "तेज़ डेटा")?

संपादित

पूरा कोड यहाँ है: https://gist.github.com/1676742, संकलन के लिए कमांड लाइन test.cpp में एक टिप्पणी में है।

डेटा फ़ाइलों को यहां हैं:

+2

कृपया आप दो परीक्षणों के पूर्ण, संकलित संस्करण प्रदान कर सकते हैं, ताकि हम उनके साथ प्रयोग कर सकें? – NPE

+0

क्या यह हो सकता है कि जब आप अपने स्पैर मैट्रिक्स में अपनी फ्लोट पर '0' पास करते हैं, तो 'int' से' float' में रूपांतरण कुछ ओवरहेड पेश करता है? –

+0

क्या आप केवल उन तत्वों को अपडेट करते हैं जो 0 नहीं हैं? तो, क्या यह हो सकता है कि शून्य कैश में नहीं हैं? – duedl0r

उत्तर

7

शायद ऐसा इसलिए है क्योंकि अपने "तेज" डेटा केवल सामान्य चल बिन्दु संख्या के होते हैं, लेकिन अपने "धीमी" है डेटा होता है बहुत से denormalized संख्याओं।

अपने दूसरे प्रश्न का सवाल है, तो आप इस के साथ गति में सुधार करने की कोशिश कर सकते हैं (और सही शून्य के रूप में सभी denormalized संख्या का इलाज):

#include <xmmintrin.h> 
_mm_setcsr(_mm_getcsr() | 0x8040); 
+0

हां वास्तव में, यदि 'स्केल' उच्च हो जाता है, तो धीमी डेटा बहुत तेज हो जाती है .. – duedl0r

2

मैं इस के दो कारण के बारे में सोच सकते हैं।

सबसे पहले, शाखा भविष्यवाणी गलत निर्णय ले रही है। कोड परिवर्तनों के बिना डेटा परिवर्तनों के कारण प्रदर्शन अंतराल का यह एक संभावित कारण है। हालांकि, इस मामले में, यह बहुत ही असंभव लगता है।

दूसरा संभावित कारण यह है कि आपके "अधिकतर शून्य" डेटा में वास्तव में ज़ीरो नहीं होते हैं, बल्कि लगभग शून्य के बजाय, या आप लगभग शून्य सीमा में arr1 रखते हैं। this Wikipedia link देखें।

+0

नहीं सोचें - रन परीक्षण। –

1

कुछ भी अजीब बात नहीं है कि आईबीन के डेटा को संसाधित करने में अधिक समय लगता है: आपके पास '1.401e-045 # DEN' या '2.214e-043 # DEN' जैसी कई संख्याएं हैं, जहां #DEN का मतलब है मानक फ्लोट परिशुद्धता के लिए सामान्यीकृत नहीं किया जा सकता है। यह देखते हुए कि आप इसे 6.6e-14 तक गुणा करने जा रहे हैं, आपको निश्चित रूप से अपूर्ण अपवाद होंगे, जो महत्वपूर्ण रूप से गणना को धीमा कर देते हैं।

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