2013-07-26 5 views
9

मैं सोच रहा था कि exp() अधिक सामान्य pow() से अधिक तेज़ है। मैं जेएसपीरफ़ http://jsperf.com/pow-vs-exp पर तेजी से बेंचमार्क चलाता हूं और यह मेरे लिए दिलचस्प परिणाम दिखाता है।Pow() बनाम एक्सपी() प्रदर्शन

Math.exp(logBase * exponent); // fastest 
Math.exp(Math.log(base) * exponent); // middle 
Math.pow(base, exponent); // slowest 

मुझे पता है कि परिणाम वास्तुकला और भाषा पर काफी भिन्न होंगे लेकिन मुझे सैद्धांतिक दृष्टिकोण में भी रूचि है। pow(a, b)exp(log(a) * b) के रूप में लागू किया गया है या क्या कुछ और चालाक तरीका है कि कैसे सह गणना शक्ति "सीधे" (सी ++, सी # या जावास्क्रिप्ट में)। क्या कुछ आर्किटेक्चर पर एक्सप, लॉग या पाउ के लिए सीपीयू निर्देश हैं?

जहाँ तक मुझे पता है, exp() और log() दोनों कुछ टेलर श्रृंखला का उपयोग करके गणना की जाती हैं और गणना करने के लिए बहुत महंगे हैं। यह मेरा विश्वास है बिजली की निरंतर आधार के लिए है कि, इस कोड

double logBase = log(123.456); 
for (int i = 0; i < 1024; ++i) { 
    exp(logBase * 654.321); 
} 

इस

for (int i = 0; i < 1024; ++i) { 
    pow(123.456, 654.321); 
} 

से बेहतर है कि सही धारणा है?

+4

मुझे आश्चर्य नहीं होगा अगर उनमें से एक विकल्प दूसरों की तुलना में काफी सटीक था। – delnan

+1

मेरे पास 2-5% के आसपास त्रुटि का मार्जिन है। कुछ बार परीक्षण चलाने की कोशिश करें।लेकिन बेंचमार्क बिल्कुल सही से दूर है। यही कारण है कि मैं इसके पीछे सिद्धांत में रूचि रखता हूं। और परिशुद्धता भी दिलचस्प सवाल है। – NightElfik

+0

यह वास्तव में कार्यान्वयन विस्तार पर निर्भर करेगा। जावास्क्रिप्ट के बारे में आपका सवाल विशेष रूप से है? –

उत्तर

9

हां, exp सामान्य रूप से pow से तेज़ होगा।

exp और log फ़ंक्शंस लक्ष्य प्लेटफ़ॉर्म के लिए अनुकूलित किए जाएंगे; कई तकनीकों ऐसे Pade सन्निकटन, रैखिक या बाइनरी कमी सन्निकटन के बाद, आदि

pow समारोह आम तौर पर exp(log(a) * b) के रूप में लागू किया जाएगा, जैसा कि आप कहते हैं कि के रूप में इस्तेमाल किया जा सकता है, तो यह स्पष्ट रूप से अकेले exp की तुलना में धीमी है।pow जैसे नकारात्मक एक्सपोनेंट्स, अभिन्न एक्सपोनेंट्स, 1/2 या 1/3 के बराबर एक्सपोनेंट्स के लिए कई विशेष मामले हैं। ये सामान्य मामले में pow धीमा कर देंगे क्योंकि ये परीक्षण महंगे हैं।

this SO question on pow देखें।

1

आंशिक उत्तर के रूप में, कुछ आर्किटेक्चर पर एक्स, लॉग या पाउ के लिए निर्देश हैं। हालांकि, इसका जरूरी अर्थ नहीं है।

उदाहरण के लिए, 86 पर वहाँ

  • f2xm1 की गणना 2 एक्स - 1
  • fscale जो गणना करता है y * 2 (int) x
  • fyl2x जो गणना करता है y * लॉग इन करें 2 x
  • fyl2xp1 जो y * लॉगकी गणना करता है2 (x + 1) (इनपुट रेंज पर प्रतिबंध हैं)

हालांकि, उनका अधिक उपयोग नहीं किया जाता है। यह आर्किटेक्चर से आर्किटेक्चर में भिन्न होता है, लेकिन वे कभी तेज़ नहीं होते हैं। एक अधिक चरम उदाहरण के रूप में, fyl2x में सैंडी ब्रिज (सुंदर हालिया!) पर 724 की विलंबता है, उस समय उसी प्रोसेसर पर आप लगभग 700 स्वतंत्र फ़्लोटिंग पॉइंट परिवर्धन, या लगभग 240 आश्रित फ़्लोटिंग पॉइंट परिवर्धन, या लगभग 2000 स्वतंत्र सरल पूर्णांक संचालन।

यह जितना खराब हो जाता है, उतना ही खराब है, लेकिन वे आम तौर पर धीमे होते हैं। इतना धीमा है कि मैन्युअल कार्यान्वयन उन्हें हरा सकता है या कम से कम महत्वपूर्ण रूप से हार नहीं सकता है।

इसके अलावा, एसएसई कोड के पक्ष में एफपीयू कोड धीरे-धीरे गायब हो रहा है। उन निर्देशों के कोई एसएसई समकक्ष नहीं हैं।

+0

एसएसई एक एफपीयू का प्रतीक है, और यह पहले से ही बड़े पैमाने पर * x87 * कोड बदल चुका है, यही कारण है कि इंटेल 'fyl2x' तेजी से बनाने में प्रयास नहीं करता है। – Potatoswatter

+0

@Potatoswatter आपको लगता है कि x87 कोड "एफपीयू कोड" को कॉल करना उचित नहीं है, हालांकि, आमतौर पर किया जाता है। यह एक वैध भेद है, एसएसई पुराने एफपीयू का उपयोग नहीं करता है। बेशक यह सीपीयू पर एक ही कार्यात्मक इकाइयों के साथ लागू किया गया है, लेकिन तार्किक रूप से वे पूरी तरह से अलग हैं। – harold

+0

यह हो सकता है या नहीं भी हो सकता है। किसी भी तरह से, एसएसई एक (वेक्टर) एफपीयू के लिए एक निर्देश सेट है, इसलिए एसएसई से अलग करने के लिए x87 कोड "एफपीयू कोड" को कॉल करना भ्रामक या भ्रमित है। बिंदु पर अधिक, x87 अप्रासंगिक है क्योंकि यह अप्रचलित है। – Potatoswatter

1

आर्किटेक्चर विवरण के बावजूद, Math.pow त्रुटि जांच के मामले में और अधिक करना है (उदाहरण के लिए, यदि आधार नकारात्मक है तो क्या होता है?)। Math.exp से अधिक (और इस तरह मैं धीमे होने के लिए pow की अपेक्षा करता हूं)।

कल्पना के प्रासंगिक भागों:

http://ecma-international.org/ecma-262/5.1/#sec-15.8.2.8

15.8.2.8 exp (x)

एक्स (ड के घातीय समारोह के लिए एक कार्यान्वयन पर निर्भर सन्निकटन रिटर्न उठाया एक्स की शक्ति, जहां ई प्राकृतिक लॉगरिदम का आधार है)।

यदि एक्स NaN है, तो परिणाम NaN है। यदि एक्स +0 है, तो परिणाम 1 है। यदि x -0 है, तो परिणाम 1 है। यदि x + ∞ है, तो परिणाम + ∞ है। यदि एक्स है- 0, परिणाम +0 है।

http://ecma-international.org/ecma-262/5.1/#sec-15.8.2.13

15.8.2.13 पॉव (एक्स, वाई)

बिजली y के एक्स को ऊपर उठाने का परिणाम के लिए एक कार्यान्वयन पर निर्भर सन्निकटन देता है।

यदि वाई NaN है, तो परिणाम NaN है। यदि y +0 है, तो परिणाम 1 है, भले ही x NaN है। यदि y -0 है, तो परिणाम 1 है, भले ही एक्स NaN है। यदि एक्स NaN है और y nonzero है, तो परिणाम NaN है। यदि पेट (एक्स)> 1 और वाई + ∞ है, तो परिणाम + ∞ है। यदि पेट (एक्स)> 1 और वाई है -∞, परिणाम +0 है। यदि abs (x) == 1 और y + ∞ है, तो परिणाम NaN है। यदि abs (x) == 1 और y है-, परिणाम NaN है। यदि abs (x) < 1 और y + ∞ है, तो परिणाम +0 है। यदि abs (x) < 1 और y is -∞, परिणाम + ∞ है। यदि एक्स + ∞ और वाई> 0 है, तो परिणाम + ∞ है। यदि एक्स + ∞ और वाई < 0 है, तो परिणाम +0 है। यदि एक्स है- y और y> 0 और y एक विषम पूर्णांक है, तो परिणाम है -∞। यदि एक्स है- y और y> 0 और y एक विषम पूर्णांक नहीं है, तो परिणाम + ∞ है। यदि एक्स है- y और y < 0 और y एक विषम पूर्णांक है, तो परिणाम -0 है। यदि एक्स है- y और y < 0 और y एक विषम पूर्णांक नहीं है, तो परिणाम +0 है। यदि एक्स +0 और y> 0 है, तो परिणाम +0 है। यदि एक्स +0 और वाई < 0 है, तो परिणाम + ∞ है। यदि एक्स -0 और वाई> 0 और वाई एक विषम पूर्णांक है, तो परिणाम -0 है। यदि एक्स -0 और y> 0 है और y एक विषम पूर्णांक नहीं है, तो परिणाम +0 है। यदि एक्स है -0 और वाई < 0 और वाई एक विषम पूर्णांक है, तो परिणाम है -∞। यदि एक्स है -0 और वाई < 0 और वाई एक विषम पूर्णांक नहीं है, तो परिणाम + ∞ है। यदि x और x परिमित है और y परिमित है और y पूर्णांक नहीं है, तो परिणाम NaN है।

+0

धन्यवाद, यह दिलचस्प है! शायद यही कारण है कि 'Math.exp (Math.log (आधार) * एक्सपोनेंट) 'Math.pow (आधार, एक्सपोनेंट)' से तेज है। यह सभी विशेष मामलों की सही गणना नहीं कर सकता है लेकिन मुझे उनकी परवाह नहीं है। – NightElfik

+0

@NightElfik प्रश्न के उत्तर के बावजूद, जब तक कि आप जेएस में भारी संख्यात्मक काम करने की योजना नहीं बना रहे हैं, मुझे संदेह है कि 'एक्सपी' और 'पाउ' का चलने का समय आपकी स्क्रिप्ट के निष्पादन समय पर हावी है। Knuth उद्धरण याद रखें "समयपूर्व अनुकूलन सभी बुराई की जड़ है" – SheetJS

+0

मुझे यह बहुत अच्छी तरह से पता है। हालांकि मेरे कोड का यह हिस्सा बहुत अधिक उपयोग किया जाता है, फिर भी मैं वास्तव में अपने कोड को तेज़ करने की कोशिश करने के बजाय इस घटना के पीछे सिद्धांत के बारे में और अधिक घूम रहा था। किसी भी प्रदर्शन अनुकूलन से पहले मैं पहले प्रोफाइलिंग करता हूं। – NightElfik

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