दिलचस्प पोस्ट
चाल चलाना w / websockets और अजगर / डीजेंगो (/ मुड़?) जावास्क्रिप्ट में क्लिक ईवेंट के साथ डायनामिक बटन का निर्माण मैं कैसे परीक्षण कर सकता हूँ अगर स्ट्रिंग में कोई अक्षर जावास्क्रिप्ट का उपयोग कर अपरकेस या लोअरकेस है? फायरबेज: सार्वजनिक / निजी उपयोगकर्ता डेटा को कैसे ढाँचा करें डीजेंगो का उपयोग करके अद्वितीय अपलोड फ़ाइल नामों को लागू करें? ट्रिग में एक पेड़ को कैसे रेंडर करना है के लिए "अस्थायी asp.NET फ़ाइलें" फ़ोल्डर क्या है? कैसे निम्न आइटमों में से एक सूची में है, यह कैसे जांचें? क्या कोई वास्तविक दुनिया समस्या है, या सिर्फ एक ऐतिहासिक एक पूरक? फ़ंक्शन के मॉड्यूल को पायथन में कॉल करने के __name__ प्राप्त करें AppCompat के लिए पूर्ण स्क्रीन थीम जावा में स्ट्रिंग () को ठीक से कैसे ओवरराइड करें? ओ (1) में अद्वितीय (गैर दोहराव) यादृच्छिक संख्याएं? Python 2.x के साथ पायथन 3.x के साथ पीईपी कैसे उपयोग करें सफ़ारी वेब अनुप्रयोगों में आईफोन और आइपॉड पर HTML5 वीडियो प्लेयर व्यवहार

एसएसई scalar sqrt (x) rsqrt (x) * x से धीमी क्यों है?

मैं इंटेल कोर डुओ पर हमारे कुछ कोर गणित की रूपरेखा करता रहा हूं, और वर्ग रूट के विभिन्न तरीकों को देखकर मैंने कुछ अजीब देखा है: एसएसई स्कैरल ऑपरेशन का उपयोग करना, यह एक पारस्परिक वर्ग रूट लेने और इसे गुणा करने के लिए तेज़ है sqrt प्राप्त करने के लिए, यह मूल sqrt opcode का उपयोग करने के लिए है!

मैं इसे एक पाश की तरह कुछ परीक्षण कर रहा हूँ:

inline float TestSqrtFunction( float in ); void TestFunc() { #define ARRAYSIZE 4096 #define NUMITERS 16386 float flIn[ ARRAYSIZE ]; // filled with random numbers ( 0 .. 2^22 ) float flOut [ ARRAYSIZE ]; // filled with 0 to force fetch into L1 cache cyclecounter.Start(); for ( int i = 0 ; i < NUMITERS ; ++i ) for ( int j = 0 ; j < ARRAYSIZE ; ++j ) { flOut[j] = TestSqrtFunction( flIn[j] ); // unrolling this loop makes no difference -- I tested it. } cyclecounter.Stop(); printf( "%d loops over %d floats took %.3f milliseconds", NUMITERS, ARRAYSIZE, cyclecounter.Milliseconds() ); } 

मैंने testSqrtFunction के लिए कुछ अलग निकायों के साथ यह करने की कोशिश की है, और मुझे कुछ समय मिल गया है जो वास्तव में मेरे सिर को खरोंच कर रहे हैं। अब तक की सबसे खराब स्थिति मूल sqrt () फ़ंक्शन का उपयोग कर रही थी और "स्मार्ट" कंपाइलर "अनुकूलन" दे रही थी। एक्सएन एफपीयू का उपयोग करते हुए 24ns / float पर, यह घृणित रूप से खराब था:

 inline float TestSqrtFunction( float in ) { return sqrt(in); } 

अगली बात मैंने कोशिश की थी जो एसईई के स्केलर sqrt opcode का उपयोग करने के लिए संकलक को मजबूर करने के लिए एक आंतरिक का उपयोग कर रहा था:

 inline void SSESqrt( float * restrict pOut, float * restrict pIn ) { _mm_store_ss( pOut, _mm_sqrt_ss( _mm_load_ss( pIn ) ) ); // compiles to movss, sqrtss, movss } 

यह 11.9ns / float पर बेहतर था मैंने कारक के निराला न्यूटन-आरपटन सन्निकटन तकनीक की भी कोशिश की , जो कि हार्डवेयर की तुलना में 4.3ns / float पर भी बेहतर था, हालांकि 2 10 में 1 की त्रुटि (जो कि मेरे उद्देश्यों के लिए बहुत अधिक है) के साथ।

दोज़ी तब था जब मैंने एसएसई सेशन को पारस्परिक वर्ग रूट के लिए प्रयोग किया और फिर वर्गमूल (x * 1 / √x = √x) प्राप्त करने के लिए एक गुणा का इस्तेमाल किया। हालांकि यह दो निर्भर कार्यों को लेता है, यह 1.24ns / float पर अब तक का सबसे तेज़ समाधान था और 2 -14 के लिए सटीक था:

 inline void SSESqrt_Recip_Times_X( float * restrict pOut, float * restrict pIn ) { __m128 in = _mm_load_ss( pIn ); _mm_store_ss( pOut, _mm_mul_ss( in, _mm_rsqrt_ss( in ) ) ); // compiles to movss, movaps, rsqrtss, mulss, movss } 

मेरा प्रश्न मूल रूप से क्या देता है ? एसएसई के दो-दूसरे गणित के संचालन से इसे संश्लेषण करने की तुलना में धीमी होने पर एसएसई का निर्मित-टू-हार्डवेयर वर्ग रूट ऑपोड धीमा क्यों है?

मुझे यकीन है कि यह वास्तव में स्वयं सेशन की लागत है, क्योंकि मैंने सत्यापित किया है:

  • सभी डेटा कैश में फिट बैठता है, और पहुंच अनुक्रमिक होते हैं
  • फ़ंक्शंस इनलाइन होते हैं
  • लूप को अनारोल्ड करना कोई फर्क नहीं पड़ता
  • संकलक झंडे पूर्ण अनुकूलन के लिए सेट हैं (और विधानसभा अच्छा है, मैंने जाँच की है)

( संपादित करें : स्टेफेनेक्ट्रोन सही तरीके से बताता है कि संख्याओं की लंबी तारों पर आपरेशनों का उपयोग वेक्टरिंग सिम पैक ऑप्स, जैसे rsqrtps – का उपयोग करना चाहिए – लेकिन सरणी डेटा संरचना यहां केवल परीक्षण उद्देश्यों के लिए है: जो मैं वास्तव में मापने की कोशिश कर रहा हूं वह उपयोग करने के लिए स्केलर प्रदर्शन है कोड जो वैक्टरयुक्त नहीं हो सकता।)

Solutions Collecting From Web of "एसएसई scalar sqrt (x) rsqrt (x) * x से धीमी क्यों है?"

sqrtss सही तरीके से गोल परिणाम देता है। rsqrtss पारस्परिक, लगभग 11 बिट्स के लिए सही करने के लिए एक सन्निकटन देता है।

sqrtss एक अधिक सटीक परिणाम पैदा कर रहा है, जब सटीकता की आवश्यकता होती है। rsqrtss मामलों के लिए मौजूद है जब एक अनुमान के मुताबिक पर्याप्त है, लेकिन गति की आवश्यकता है। यदि आप इंटेल के दस्तावेज पढ़ते हैं, तो आपको एक अनुदेश अनुक्रम (एकल न्यूटन-रेफसन कदम के बाद पारस्परिक वर्ग-रूट सन्निकटन भी मिलेगा) जो लगभग पूर्ण परिशुद्धता देता है (~ 23 बिट सटीकता, अगर मुझे ठीक से याद है), और अभी कुछ हद तक है sqrtss से तेज

संपादित करें: यदि गति महत्वपूर्ण है, और आप वास्तव में कई मानों के लिए एक पाश में इसे कॉल कर रहे हैं, तो आपको इन निर्देशों, rsqrtps या sqrtps rsqrtps संस्करणों का उपयोग करना चाहिए, दोनों प्रक्रियाओं में प्रति निर्देश चार फ्लोट की प्रक्रिया है।

विभाजन के लिए यह भी सच है MULSS (ए, आरसीपीएसएस (बी)) डीआईवीएसएस (ए, बी) से अधिक तेजी से है। वास्तव में यह अभी भी तेज़ है, जब आप न्यूटन-रपसन पुनरावृत्ति के साथ अपनी सटीकता बढ़ाते हैं।

इंटेल और एएमडी दोनों अपने अनुकूलन मैनुअल में इस तकनीक की सिफारिश करते हैं। आईईईई -754 अनुपालन की आवश्यकता नहीं है, जो अनुप्रयोगों में, div / sqrt का उपयोग करने के लिए एकमात्र कारण कोड पठनीयता है।

जवाब देने की बजाए, यह वास्तव में गलत हो सकता है (मैं भी कैश और अन्य सामान के बारे में जांच या बहस नहीं कर रहा हूँ, मान लें कि वे समान हैं) मैं आपको उस स्रोत को इंगित करने का प्रयास करूंगा जो आपके प्रश्न का उत्तर दे सके।
अंतर कैसे sqrt और rsqrt गणना कर रहे हैं में झूठ हो सकता है। आप यहां अधिक पढ़ सकते हैं http://www.intel.com/products/processor/manuals/ मुझे लगता है कि आप उपयोग कर रहे हैं प्रोसेसर कार्यों के बारे में पढ़ने से शुरू करने के लिए सुझाव है, वहाँ कुछ जानकारी, विशेष रूप से rsqrt के बारे में (सीपीयू भारी सन्निकटन के साथ आंतरिक लुकअप तालिका का उपयोग कर रहा है, जो परिणाम प्राप्त करने के लिए बहुत आसान बनाता है)। यह प्रतीत हो सकता है कि, rsqrt sqrt की तुलना में बहुत तेज है, कि 1 अतिरिक्त मौलर ऑपरेशन (जो महंगा नहीं है) यहां स्थिति को बदल नहीं सकता है।

संपादित करें: कुछ तथ्य जो उल्लेख के लायक हो सकते हैं:
1. एक बार जब मैं अपने ग्राफिक्स पुस्तकालय के लिए कुछ सूक्ष्म ऑप्टिमाइटलेशंस कर रहा था और मैंने वैक्टर की लंबाई कंप्यूटिंग के लिए rsqrt का उपयोग किया है। (sqrt के बजाय, मैंने अपनी राशि को इसके आरएसक्यूटी के द्वारा गुणा किया है, जो आपके परीक्षणों में ठीक है), और यह बेहतर प्रदर्शन किया।
2. साधारण लुकअप तालिका का उपयोग कर rsqrt कंप्यूटिंग आसान हो सकता है, rsqrt के लिए, जब एक्स अनन्तता में जाता है, 1 / sqrt (x) 0 पर जाता है, इसलिए छोटे x के लिए फ़ंक्शन वैल्यू परिवर्तित नहीं होता है (बहुत), जबकि sqrt – यह अनन्तता को जाता है, तो यह वह सरल मामला है;)

साथ ही, स्पष्टीकरण: मुझे यकीन नहीं है कि मैंने उन किताबों में यह पाया है जहां मैंने लिंक किया है, लेकिन मुझे पूरा यकीन है कि मैंने पढ़ा है कि आरएसक्यूटी कुछ लुकअप तालिका का उपयोग कर रहा है, और इसका इस्तेमाल केवल तब ही किया जाना चाहिए, जब परिणाम सही होने की आवश्यकता नहीं है, हालांकि – मैं गलत भी हो सकता है, क्योंकि यह कुछ समय पहले था :)।

न्यूटन-रफ़सन शून्य के f(x) बराबर होता है, जो कि वेतन वृद्धि का उपयोग करके -f/f' बराबर होता है जहां f' व्युत्पन्न होता है।

x=sqrt(y) , आप f(x) = x^2 - y का उपयोग करके x लिए f(x) = 0 को हल करने का प्रयास कर सकते हैं;

फिर वेतन वृद्धि है: dx = -f/f' = 1/2 (x - y/x) = 1/2 (x^2 - y) / x जिसमें उसमें धीमी गति से विभाजित है

आप अन्य कार्यों (जैसे f(x) = 1/y - 1/x^2 ) की कोशिश कर सकते हैं, लेकिन वे समान रूप से जटिल हो जाएंगे।

चलिए अब 1/sqrt(y) आप f(x) = x^2 - 1/y कोशिश कर सकते हैं, लेकिन यह उतना ही जटिल होगा: उदाहरण के लिए dx = 2xy / (y*x^2 - 1) f(x) लिए एक गैर-स्पष्ट वैकल्पिक विकल्प है: f(x) = y - 1/x^2

उसके बाद: dx = -f/f' = (y - 1/x^2) / (2/x^3) = 1/2 * x * (1 - y * x^2)

आह! यह एक तुच्छ अभिव्यक्ति नहीं है, लेकिन आप केवल उस में बहुमूल्य है, कोई विभाजन नहीं। => तेज!

और: पूर्ण अद्यतन चरण new_x = x + dx तब पढ़ता है:

x *= 3/2 - y/2 * x * x जो भी आसान है

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