2012-12-29 9 views
18

मैं कुछ भारी सीपीयू बाध्य समस्या पर काम कर रहा हूं। जब मैं inline कीवर्ड का उपयोग करता हूं तो मुझे एक बड़ा प्रदर्शन सुधार दिखाई देता है। मैं एक कस्टम कुंजी comparer में मानक .net पुस्तकालय गुजर से एक शब्दकोश बनाने Eq_cmpएफ # इनलाइन कारण 11x प्रदर्शन सुधार क्यों करता है

पर इनलाइन कीवर्ड का उपयोग Eq_cmp

> perf_run 10000000 ;; 
Real: 00:00:11.039, CPU: 00:00:11.029, GC gen0: 771, gen1: 3, gen2: 1 
val it : unit =() 

पर इनलाइन कीवर्ड के बिना नीचे

https://gist.github.com/4409734

कोड और समय परिणामों को देखने के

perf_run 10000000 ;; 
Real: 00:00:01.319, CPU: 00:00:01.388, GC gen0: 1, gen1: 1, gen2: 1 
val it : unit =() 
> 

मैंने आईएनएल के साथ जनरल 0 जीसी की मात्रा में भारी अंतर भी देखा इन कोड और गैर रेखांकित कोड।

कोई बता सकता है कि इतना बड़ा अंतर क्यों है?

+0

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

+1

एफ # में जेनेरिक समानता परीक्षण धीमे हैं। मुझे लगता है कि यह अनिवार्य रूप से वही समस्या है जैसा कि यहां चर्चा की गई है: http://stackoverflow.com/questions/6104221/why-is-this-f-code-so-slow/6104300#6104300 –

उत्तर

17

मैं inline कीवर्ड जोड़ने के बाद 3x प्रदर्शन बूस्ट के साथ अपनी मशीन पर व्यवहार को पुन: उत्पन्न कर सकता हूं।

ILSpy के तहत दोनों तरफ से दो संस्करणों को डीकंपलिंग लगभग समान सी # कोड देता है। उल्लेखनीय अंतर दो समानता परीक्षण में है:

// Version without inline 
bool IEqualityComparer<Program.Pair<a>>.System-Collections-Generic-IEqualityComparer(Program.Pair<a> x, Program.Pair<a> y) 
{ 
    a [email protected] = [email protected]; 
    a [email protected] = [email protected]; 
    if (LanguagePrimitives.HashCompare.GenericEqualityIntrinsic<a>([email protected], [email protected])) 
    { 
     a [email protected] = [email protected]; 
     a [email protected] = [email protected]; 
     return LanguagePrimitives.HashCompare.GenericEqualityIntrinsic<a>([email protected], [email protected]); 
    } 
    return false; 
} 

// Version with inline 
bool IEqualityComparer<Program.Pair<int>>.System-Collections-Generic-IEqualityComparer(Program.Pair<int> x, Program.Pair<int> y) 
{ 
    int [email protected] = [email protected]; 
    int [email protected] = [email protected]; 
    if ([email protected] == [email protected]) 
    { 
     int [email protected] = [email protected]; 
     int [email protected] = [email protected]; 
     return [email protected] == [email protected]; 
    } 
    return false; 
} 

सामान्य समानता बहुत कम विशेष संस्करण की तुलना में कुशल है।

मैंने इनलाइन कोड और गैर रेखांकित कोड के साथ जनरल 0 जीसी की मात्रा में भारी अंतर भी देखा।

कोई बता सकता है कि इतना बड़ा अंतर क्यों है?

F# source code में GenericEqualityIntrinsic समारोह पर एक नज़र ले रहा है:

let rec GenericEqualityIntrinsic (x : 'T) (y : 'T) : bool = 
    fsEqualityComparer.Equals((box x), (box y)) 

यह करता तर्कों पर मुक्केबाजी, जो अपने पहले उदाहरण में कचरे के महत्वपूर्ण राशि बताते हैं। जब जीसी अक्सर खेलता है, तो यह नाटकीय रूप से गणना को धीमा कर देगा। दूसरा उदाहरण (inline का उपयोग करके) Pair संरचना के दौरान लगभग कोई कचरा उत्पन्न नहीं करता है।

यह कहा गया है कि यह कॉल साइट पर एक विशेष संस्करण का उपयोग होने पर inline कीवर्ड का अपेक्षित व्यवहार है। मेरा सुझाव हमेशा एक ही मानक पर अपने कोड को अनुकूलित और मापने का प्रयास करना है।

आपको एक बहुत ही समान धागे Why is this F# code so slow? में रुचि हो सकती है।

+0

धन्यवाद कि चीजों को साफ़ किया गया –

15

प्रकार विशेषज्ञता

inline के बिना, आप सामान्य तुलना जो बहुत अक्षम है प्रयोग कर रहे हैं। inline के साथ, सामान्यता को हटा दिया गया है और int तुलना सीधे उपयोग की जाती है।

+0

मेरे पास दो असम्बद्ध डाउनवॉट क्यों हैं ?! –

+0

यह जानना दिलचस्प है कि ओकैम इसे कैसे संभालता है, क्योंकि इनलाइन AFAIK –

+3

@ उपयोगकर्ता 125 ओकैमल वास्तव में बहुत बुरी तरह से संभालता है। स्टोर करने के लिए कम से कम 1 शब्द की आवश्यकता वाले प्रत्येक मान को डिफ़ॉल्ट रूप से बॉक्स किया जाता है (हालांकि फ्लोट के अनबॉक्स एरेज़ के लिए एक विशेष मामला है लेकिन यह सभी सरणी पर रन-टाइम प्रकार परीक्षण करता है)। प्रत्येक जेनेरिक फ़ंक्शन रन-टाइम प्रेषण के माध्यम से बहुरूपता करता है, जो धीमा होता है। इनलाइनिंग सबसे अच्छा है (छोटे पत्ते के कार्यों को रेखांकित किया जाता है) लेकिन मज़दूर सीमाओं से भी बाधित होता है। तो OCaml's Hashtbl.t (टैग की गई) कुंजी और मानों की सूची (ढेर-आवंटित) की एक सरणी है। कस्टम तुलना और हैशिंग का मतलब मज़ेदार है जिसका मतलब टूटा हुआ है। –

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