2016-04-08 6 views
15

अधिकतर, मैं अब आईएनसी और डीईसी से दूर रहता हूं, क्योंकि वे आंशिक कंडीशन कोड अपडेट करते हैं, और इससे पाइपलाइन में अजीब स्टालों का कारण बन सकता है, और एडीडी/एसयूबी नहीं है। तो जहां इससे कोई फर्क नहीं पड़ता (अधिकांश स्थान), मैं स्टालों से बचने के लिए एडीडी/एसयूबी का उपयोग करता हूं। मैं कोड छोटे मामलों को ध्यान में रखते हुए केवल आईएनसी/डीईसी का उपयोग करता हूं, उदाहरण के लिए, कैश लाइन में फ़िट करना जहां का आकार एक या दो निर्देशों के मामले में पर्याप्त अंतर बनाता है। यह शायद पॉइंटलेस नैनो [शाब्दिक!] - अनुकूलन है, लेकिन मैं अपनी कोडिंग आदतों में पुराना स्कूल हूं।आईएनसी निर्देश बनाम एडीडी 1: क्या इससे कोई फर्क पड़ता है?

लेखक: @Ira बैक्सटर

ऊपर टुकड़ा से why the INC and DEC instructions do not affect the carry flag?

आता है और मैं पूछने के लिए कारण है कि यह पाइप लाइन में स्टालों पैदा कर सकता है, जबकि नहीं जोड़ता है चाहते हैं? आखिरकार, दोनों ऐड और इंक फ्लैग रजिस्ट्रार अपडेट करते हैं। केवल अंतर यह है कि inc सीएफ अद्यतन नहीं करता है। लेकिन यह क्यों मायने रखता है?

+1

@ हंसपैसेंट: यह अब गलत है कि पी 4 अप्रासंगिक है। इंटेल और एएमडी सीपीयू * अलग * अलग-अलग झंडे का नाम बदलते हैं (मुझे लगता है कि वर्चुअलाइज्ड द्वारा इसका मतलब है), इसलिए 'inc/dec' के पास 'EFLAGS' के पुराने मान पर झूठी निर्भरता नहीं है। अनुकूलन मैनुअल बस अद्यतन नहीं किया गया है। –

+0

[आईएनसी से 1 वास्तव में तेजी से जोड़ा गया है? x86] (http://stackoverflow.com/q/13383407/995714) –

उत्तर

27

आधुनिक CPUs पर, addinc की तुलना में धीमी कभी नहीं (अप्रत्यक्ष कोड आकार/डिकोड प्रभाव को छोड़कर) है, लेकिन आमतौर पर यह या तो, नहीं तेज है ताकि आप कोड आकार कारणों के लिए inc को प्राथमिकता देनी चाहिए। विशेष रूप से यदि यह विकल्प एक ही बाइनरी में कई बार दोहराया जाता है (उदाहरण के लिए यदि आप एक कंपाइलर-लेखक हैं)।

inc 1 बाइट (64-बिट मोड), या 2 बाइट्स (opcodes 0x40..F inc r32/dec r32 32-बिट मोड में संक्षिप्त रूप, REX उपसर्ग के रूप में x86-64 के लिए सोद्देश्य) बचाता है। यह कुल कोड आकार में एक छोटा प्रतिशत अंतर बनाता है। यह निर्देश-कैश हिट दर, आईटीएलबी हिट दर, और डिस्क से लोड होने वाले पृष्ठों की संख्या में सहायता करता है।

inc के लाभ:

  • कोड आकार सीधे
  • नहीं एक तत्काल का उपयोग कर Sandybridge-परिवार पर UOP-कैश प्रभाव हो सकता है, जो add के बेहतर सूक्ष्म संलयन ऑफसेट सकता है। (Agner Fog's table 9.1 in the Sandybridge section of his microarch guide देखें।) परफ काउंटर आसानी से समस्या-चरण यूपीएस को माप सकते हैं, लेकिन यह मापना मुश्किल है कि यूओपी कैश और यूओपी-कैश में चीजें कैसे पैक की जाती हैं बैंडविड्थ प्रभाव पढ़ें।
  • सीएफ अनमोडिफाइड छोड़ना कुछ मामलों में सीपीयू पर एक लाभ है जहां आप बिना स्टॉल के inc के बाद सीएफ पढ़ सकते हैं।(Nehalem पर और पहले नहीं।)

आधुनिक CPUs के बीच एक अपवाद नहीं है: Silvermont/Goldmont/नाइट लैंडिंग 1 UOP के रूप में डीकोड inc/dec कुशलता, लेकिन आवंटन में/2 के लिए विस्तारित नाम बदलें (उर्फ मुद्दा) मंच। अतिरिक्त यूओपी आंशिक झंडे विलय करता है। inc throughput is only 1 per clock, vs. 0.5c (or 0.33c Goldmont) for independent add r32, imm8 फ्लैग-विलय यूप्स द्वारा बनाई गई डेप चेन की वजह से।

पी 4 के विपरीत, रजिस्टर परिणाम में झंडे पर झूठा-डिप्टी नहीं है (नीचे देखें), इसलिए आउट ऑफ़ ऑर्डर निष्पादन फ़्लैग-विलय को विलंबता महत्वपूर्ण पथ से विलय करता है जब ध्वज परिणाम का उपयोग नहीं करता है। (लेकिन ओओओ विंडो मुख्यधारा के सीपीयू जैसे हैसवेल या रेजेन की तुलना में बहुत छोटी है।) inc चलाना 2 अलग-अलग यूप्स शायद ज्यादातर मामलों में सिल्वरमोंट के लिए एक जीत है; अधिकांश x86 निर्देश इन झंडे निर्भरता श्रृंखलाओं को तोड़कर, उन्हें पढ़ने के बिना सभी झंडे लिखते हैं।

SMont/KNL डिकोड के बीच एक कतार है और आवंटित/नाम बदलने (Intel's optimization manual, figure 16-2 देखें) इसलिए इस मुद्दे को दौरान 2 UOPs के विस्तार (एक-संकार्य mul, या pshufb की तरह निर्देश है, जो 1 से अधिक उत्पादन पर डिकोड स्टालों से बुलबुले भर सकते हैं डिकोडर से यूओपी और माइक्रोकोड के लिए 3-7 चक्र स्टॉल का कारण बनता है)। या सिल्वरमोंट पर, केवल 3 से अधिक उपसर्गों (बचने के बाइट्स और अनिवार्य उपसर्ग सहित) के साथ एक निर्देश, उदा। आरईएक्स + कोई एसएसएसई 3 या एसएसई 4 निर्देश। लेकिन ध्यान दें कि एक ~ 28 यूओपी पाश बफर है, इसलिए छोटे डिक इन डिकोड स्टालों से पीड़ित नहीं हैं।

inc/dec केवल निर्देश है कि 1 के रूप में डिकोड लेकिन मुद्दा 2 के रूप में नहीं कर रहे हैं: push/pop, call/ret, और lea 3 के साथ घटक भी ऐसा करते हैं। तो केएनएल के AVX512 निर्देश इकट्ठा करें। स्रोत: Intel's optimization manual, 17.1.2 आउट ऑफ़ ऑर्डर इंजन (केएनएल)। यह केवल एक छोटा थ्रूपुट जुर्माना है (और कभी-कभी यह भी नहीं कि अगर कुछ भी एक बड़ी बाधा है), तो आमतौर पर "जेनेरिक" ट्यूनिंग के लिए inc का उपयोग करना ठीक है।


इंटेल के अनुकूलन के मैनुअल अभी भी add 1 सामान्य रूप में inc से अधिक की सिफारिश की, आंशिक-ध्वज स्टालों के जोखिम से बचने के लिए। लेकिन चूंकि इंटेल का कंपाइलर डिफ़ॉल्ट रूप से ऐसा नहीं करता है, इसलिए यह संभावना नहीं है कि भविष्य के सीपीयू inc सभी मामलों में धीमे हो जाएंगे, जैसे पी 4 ने किया था।

Clang 5.0 and Intel's ICC 17 (on Godbolt) गति के लिए ऑप्टिमाइज़ करते समय inc का उपयोग करें (-O3), केवल आकार के लिए नहीं। -mtune=pentium4 उन्हें inc/dec से बचने में मदद करता है, लेकिन डिफ़ॉल्ट -mtune=generic P4 पर अधिक वजन नहीं डालता है।

ICC17 -xMIC-AVX512 (जीसीसी के -march=knl के बराबर) inc से बचने करता है, जो शायद Silvermont/KNL के लिए सामान्य रूप में एक अच्छा शर्त है। लेकिन यह आमतौर पर inc का उपयोग करने के लिए एक प्रदर्शन आपदा नहीं है, इसलिए अधिकांश कोड में inc/dec का उपयोग करने के लिए संभवतः "जेनेरिक" ट्यूनिंग के लिए उपयुक्त है, खासकर जब ध्वज परिणाम महत्वपूर्ण पथ का हिस्सा नहीं है।


Silvermont के अलावा, यह ज्यादातर-बासी अनुकूलन सलाह Pentium4 से बचे है। आधुनिक सीपीयू पर, केवल एक समस्या है यदि आप वास्तव में एक ध्वज पढ़ते हैं जो पिछले इन्सन द्वारा लिखा नहीं गया था जो लिखा था झंडे।e.g. in BigInteger adc loops. (और उस स्थिति में, यदि आप ऐसा add का उपयोग कर अपने कोड टूट जाएगा सीएफ को संरक्षित करने की जरूरत है।)

add EFLAGS रजिस्टर में सभी हालत-झंडा बिट्स लिखता है। पंजीकरण-नामकरण आउट-ऑफ-ऑर्डर निष्पादन के लिए केवल लिखना आसान बनाता है: write-after-write and write-after-read hazards देखें। add eax, 1 और add ecx, 1 समानांतर में निष्पादित कर सकते हैं क्योंकि वे एक-दूसरे से पूरी तरह से स्वतंत्र हैं। (यहां तक ​​कि Pentium4 का नाम बदलता हालत झंडा बिट्स, EFLAGS के बाकी हिस्सों से अलग के बाद से भी add बीच में आता है-सक्षम और कई अन्य बिट्स असंशोधित छोड़ देता है।)

पी 4, inc पर और dec सब के पिछले मूल्य पर निर्भर करती है झंडे, इसलिए वे एक-दूसरे के साथ समानांतर या ध्वज-सेटिंग निर्देशों के साथ समानांतर में निष्पादित नहीं कर सकते हैं। (उदाहरण के लिए add eax, [mem]/inc ecxincadd के बाद तक प्रतीक्षा करें, भले ही एड के लोड कैश में चूक जाए।) इसे झूठी निर्भरता कहा जाता है। आंशिक ध्वज झंडे के पुराने मूल्य को पढ़कर, सीएफ के अलावा बिट्स को अद्यतन करके, फिर पूर्ण झंडे लिखकर काम लिखता है।

(एएमडी के सहित), अलग झंडे के विभिन्न भागों का नाम बदलने, अन्य सभी बाहर के आदेश 86 सीपीयू तो आंतरिक रूप से वे एक लेख केवल सीएफ को छोड़कर सभी झंडे को अपडेट करते हैं। (स्रोत: Agner Fog's microarchitecture guide)। adc या cmc जैसे कुछ ही निर्देश, वास्तव में पढ़ते हैं और फिर झंडे लिखते हैं। लेकिन shl r, cl (नीचे देखें)।


जिन मामलों add dest, 1, inc dest बेहतर है कम से कम इंटेल पी 6/SNB uarch परिवारों के लिए:, add [rdi], 1 कर सकते हैं micro-fuse the store and the load+add on Intel Core2 and SnB-family तो यह 2 जुड़े हुए-डोमेन है:

  • मेमोरी-गंतव्य यूओएस/4 अप्रयुक्त-डोमेन यूओएस।
    inc [rdi] केवल स्टोर को माइक्रो-फ़्यूज़ कर सकता है, इसलिए यह 3F/4U है।
    एग्नेर फोग की टेबल के अनुसार, एएमडी और सिल्वरमॉन्ट मेमोरी-डेस्ट inc और add चलाते हैं, एक मैक्रो-ओप/यूओपी के समान।

    लेकिन add [label], 1 के साथ यूओपी-कैश प्रभावों से सावधान रहें, जिसे 32-बिट पते और एक ही यूओपी के लिए 8-बिट तत्काल आवश्यकता है।

  • एक चर गिनती पारी से पहले/बारी बारी से झंडे पर निर्भरता को तोड़ने और आंशिक-ध्वज विलय से बचने के लिए: shl reg, cl दुर्भाग्यपूर्ण CISC इतिहास की वजह से, झंडे पर एक इनपुट निर्भरता है: it has to leave them unmodified if the shift count is 0

    इंटेल एसएनबी-परिवार पर, चर-गिनती बदलाव 3 यूओप्स (कोर 2/नेहलेम पर 1 से ऊपर) हैं। AFAICT, दो यूओएस फ्लैग पढ़ते/लिखते हैं, और एक स्वतंत्र यूओपी reg और cl पढ़ता है, और reg लिखता है। यह थ्रूपुट (1.5 सी) की तुलना में बेहतर विलंबता (1 सी + अपरिहार्य संसाधन संघर्ष) होने का एक अजीब मामला है, और केवल झंडे पर निर्भरता को तोड़ने वाले निर्देशों के साथ मिश्रित होने पर अधिकतम थ्रूपुट प्राप्त करने में सक्षम होना। (I posted more about this एग्नेर फोग के मंच पर)। जब संभव हो तो BMI2 shlx का उपयोग करें; यह 1 यूओपी है और गिनती किसी भी रजिस्टर में हो सकती है।

    वैसे भी, inc (झंडे लेखन लेकिन CF असंशोधित छोड़ने) अलग-अलग गिनती shl से पहले एक झूठी निर्भरता जो कुछ पर सीएफ पिछले लिखा था के साथ छोड़ देता है, और SNB पर/IVB झंडे मर्ज करने के लिए एक अतिरिक्त UOP की आवश्यकता होती है सकते हैं।

    कोर 2/नेहलेम झंडे पर झूठे डिप्टी से बचने के लिए प्रबंधन करते हैं: मेरॉम प्रति सेकंड लगभग दो बदलावों पर 6 स्वतंत्र shl reg,cl निर्देशों का एक लूप चलाता है, सीएल = 0 या सीएल = 13 के साथ समान प्रदर्शन। प्रति घड़ी 1 से बेहतर कुछ भी साबित करता है कि झंडे पर कोई इनपुट-निर्भरता नहीं है।

    मैं shl edx, 2 और shl edx, 0 (तत्काल गिनती पाली) के साथ छोरों कोशिश की, लेकिन Core2, HSW, या एसकेएल पर dec और sub जो गति अंतर नहीं देखा था। मुझे एएमडी के बारे में पता नहीं है।

अद्यतन: इंटेल पी 6-परिवार पर अच्छा पारी प्रदर्शन एक बड़े प्रदर्शन गड्ढे की लागत है जो आप से बचने की जरूरत पर आता है: : एक अनुदेश एक पारी शिक्षा का झंडा परिणाम पर निर्भर करता है जब फ्रंट एंड स्टॉल तक निर्देश है सेवानिवृत्त (स्रोत: Intel's optimization manual, (Section 3.5.2.6: Partial Flag Register Stalls))। तो shr eax, 2/jnz इंटेल प्री-सैंडब्रिज पर प्रदर्शन के लिए बहुत विनाशकारी है, मुझे लगता है! यदि आप नेहलेम और इससे पहले की देखभाल करते हैं तो shr eax, 2/test eax,eax/jnz का उपयोग करें। इंटेल के उदाहरण यह स्पष्ट करते हैं कि यह तत्काल-गणना शिफ्ट पर लागू होता है, न केवल गिनती = cl

इंटेल कोर माइक्रोआर्किटेक्चर के आधार पर प्रोसेसर में [इसका मतलब है कोर 2 और बाद में], 1 से तत्काल स्थानांतरित करें विशेष हार्डवेयर द्वारा संभाला जाता है जैसे कि इसे आंशिक ध्वज स्टॉल का अनुभव नहीं होता है।

इंटेल वास्तव में विशेष रूप से विशेष ओपोड का मतलब नहीं है, जो एक अंतर्निहित 1 द्वारा बदलता है। मुझे लगता है कि shr eax,1 एन्कोडिंग के दो तरीकों के बीच प्रदर्शन अंतर है (मूल 8086 ऑपोड D1 /5 का उपयोग करके) केवल-लिखने वाले (आंशिक) ध्वज परिणाम का उत्पादन करते हैं, लेकिन लंबे एन्कोडिंग (C1 /5, imm8 तत्काल 1 के साथ) नहीं निष्पादन समय तक 0 के लिए तत्काल चेक किया गया है, लेकिन आउट-ऑफ-ऑर्डर मशीनरी में ध्वज आउटपुट को ट्रैक किए बिना।

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

अद्यतन: SNB-परिवार पर चर गिनती बदलाव के लिए, इंटेल के अनुकूलन के मैनुअल का कहना है:

3.5.1.6 चर बिट गणना रोटेशन और शिफ्ट

इंटेल माइक्रोआर्किटेक्चर कोड नाम सैंडी ब्रिज में, "आरओएल/आरओआर/एसएचएल/एसएचआर रेग, सीएल" निर्देश में तीन माइक्रो-ऑप्स हैं। जब ध्वज परिणाम की आवश्यकता नहीं होती है, तो इन माइक्रो-ऑप्स में से एक को त्याग दिया जा सकता है, कई सामान्य उपयोगों में बेहतर प्रदर्शन प्रदान करता है। जब ये निर्देश आंशिक ध्वज परिणामों को अद्यतन करते हैं जिन्हें बाद में उपयोग किया जाता है, तो पूर्ण तीन माइक्रो-ऑप्स प्रवाह निष्पादन और सेवानिवृत्ति पाइपलाइन, धीमे प्रदर्शन का अनुभव करना चाहिए।इंटेल माइक्रोआर्किटेक्चर कोड नाम आइवी ब्रिज में, अद्यतन आंशिक ध्वज परिणाम का उपयोग करने के लिए पूर्ण तीन माइक्रो-ऑप्स प्रवाह को निष्पादित करने में अतिरिक्त देरी होती है।

पर विचार करें नीचे फंस अनुक्रम:

loop: 
    shl eax, cl 
    add ebx, eax 
    dec edx ; DEC does not update carry, causing SHL to execute slower three micro-ops flow 
    jnz loop 

दिसम्बर अनुदेश झंडा कैरी संशोधित नहीं करता है। नतीजतन, एसएचएल ईएक्स, सीएल निर्देश को बाद के पुनरावृत्तियों में तीन माइक्रो-ऑप्स प्रवाह को निष्पादित करने की आवश्यकता है। एसयूबी निर्देश सभी झंडे अद्यतन करेगा। DECSUB के साथ SHL EAX, CL को दो माइक्रो-ऑप्स प्रवाह निष्पादित करने की अनुमति देगा।


शब्दावली

आंशिक-ध्वज स्टालों हो सकता है जब झंडे पढ़ रहे हैं, अगर वे बिल्कुल भी। पी 4 में कभी आंशिक-झंडा स्टालों नहीं हैं, क्योंकि उन्हें कभी विलय करने की आवश्यकता नहीं है। इसकी बजाय झूठी निर्भरताएं हैं।

कई उत्तरों/टिप्पणियां शब्दावली को मिलाती हैं। वे झूठी निर्भरता का वर्णन करते हैं, लेकिन फिर इसे आंशिक-ध्वज स्टॉल कहते हैं। यह एक मंदी है जो केवल कुछ झंडे लिखने के कारण होती है, लेकिन "आंशिक-ध्वज स्टॉल" प्री-एसएनबी इंटेल हार्डवेयर पर होता है जब आंशिक-ध्वज लिखने को विलय करना होता है। इंटेल एसएनबी-पारिवारिक सीपीयू बिना किसी रुकावट के झंडे मर्ज करने के लिए एक अतिरिक्त यूओपी डालते हैं। नेहलेम और ~ 7 चक्रों के लिए पहले स्टॉल। मुझे यकीन नहीं है कि एएमडी सीपीयू पर जुर्माना कितना बड़ा है।

(ध्यान दें कि आंशिक-पंजीकरण दंड हमेशा आंशिक-झंडे के समान नहीं होते हैं, नीचे देखें)।

### Partial flag stall on Intel P6-family CPUs: 
bigint_loop: 
    adc eax, [array_end + rcx*4] # partial-flag stall when adc reads CF 
    inc rcx      # rcx counts up from negative values towards zero 
    # test rcx,rcx # eliminate partial-flag stalls by writing all flags, or better use add rcx,1 
    jnz 
# this loop doesn't do anything useful; it's not normally useful to loop the carry-out back to the carry-in for the same accumulator. 
# Note that `test` will change the input to the next adc, and so would replacing inc with add 1 

अन्य मामलों में, जैसे में एक आंशिक ध्वज लिखने के बाद एक पूर्ण झंडा लिखना, या inc द्वारा लिखे गए केवल झंडे का एक पठन ठीक है। एसएनबी-परिवार सीपीयू पर, inc/dec can even macro-fuse with a jcc, the same as add/sub

पी 4 के बाद, इंटेल ने लोगों को -mtune=pentium4 के साथ फिर से संकलित करने की कोशिश करने को छोड़ दिया या गंभीर बाधाओं से बचने के लिए हाथ से लिखित एएसएम को संशोधित करने की कोशिश की। (एक विशिष्ट माइक्रोआर्किटेक्चर के लिए ट्यूनिंग हमेशा एक चीज होगी, लेकिन पी 4 पिछले सीपीयू पर तेजी से उपयोग की जाने वाली कई चीजों को कम करने में असामान्य था, और इस प्रकार मौजूदा बाइनरी में आम थे।) पी 4 चाहता था कि लोग आरआईएससी-जैसे x86 का सबसेट, और शाखा-भविष्यवाणी संकेत भी जेसीसी निर्देशों के उपसर्ग के रूप में संकेत था। (इसमें अन्य गंभीर समस्याएं भी थीं, जैसे ट्रेस कैश जो कि काफी अच्छा नहीं था, और कमजोर डिकोडर्स जिसका मतलब ट्रेस-कैश मिस पर खराब प्रदर्शन था। उल्लेखनीय नहीं है कि घड़ी के पूरे दर्शन में बिजली की घनत्व दीवार ।)

इंटेल पी 4 (नेटबर्स्ट uarch) को छोड़ दिया है, वे पी 6-परिवार डिजाइन (पेंटियम एम/Core2/Nehalem) जो उनके आंशिक-ध्वज/आंशिक-reg पहले पी 6-परिवार सीपीयू से निपटने विरासत में मिला है (है Ppro को लौट पीआईआईआई को) जो नेटबर्स्ट गलत कदम से पूर्व-दिनांकित था। (पी 4 के बारे में सबकुछ स्वाभाविक रूप से खराब नहीं था, और कुछ विचार सैंड्रिब्रिज में फिर से दिखाई दिए, लेकिन समग्र नेटबर्स्ट को व्यापक रूप से गलती माना जाता है।) कुछ बहुत सीआईएससी निर्देश बहु-निर्देश विकल्पों की तुलना में धीमे हैं, उदाहरण के लिए enter, loop, या bt [mem], reg (क्योंकि reg का मान प्रभावित करता है कि कौन सा मेमोरी पता उपयोग किया जाता है), लेकिन ये पुराने CPUs में धीमे थे इसलिए कंपेलरों ने पहले से ही उन्हें टाला था।

पेंटियम-एम ने आंशिक-रेग (निचले विलय की दंड) के लिए भी हार्डवेयर समर्थन में सुधार किया। सैंडब्रिज में, इंटेल ने आंशिक-झंडा और आंशिक-रे रेनिंग रखा और विलय की आवश्यकता होने पर इसे और अधिक कुशल बना दिया (यूओपी को बिना या न्यूनतम स्टाल के साथ डाला गया)। एसएनबी ने बड़े आंतरिक परिवर्तन किए और इसे एक नया यूरा परिवार माना जाता है, भले ही इसे नेहलेम से बहुत कुछ मिलता है, और पी 4 के कुछ विचार। (लेकिन ध्यान दें कि SNB के डीकोड-UOP कैश, निशान कैश नहीं है, हालांकि, तो यह विकोडक throughput/बिजली समस्या यह है कि नेटबर्स्ट के निशान कैश का समाधान करने की कोशिश की करने के लिए एक बहुत ही अलग समाधान है।)


के लिए उदाहरण, inc al और inc ah पी 6/एसएनबी-परिवार CPU पर समानांतर में चलाया जा सकता है, लेकिन eax पढ़ने के बाद विलय की आवश्यकता है।

पूर्ण reg पढ़ने के दौरान 5-6 चक्रों के लिए पीपीआरओ/पीआईआईआई स्टॉल। आंशिक regs के लिए विलय करने वाले यूओपी डालने के दौरान Core2/Nehalem केवल 2 या 3 चक्रों के लिए स्टाल करता है, लेकिन आंशिक झंडे अभी भी एक लंबा स्टॉल हैं।

एसएनबी झंडे के बिना, बिना रुकावट के एक विलय यूओप डालता है। इंटेल की ऑप्टिमाइज़ेशन गाइड का कहना है कि व्यापक रेग में एएच/बीएच/सीएच/डीएच विलय करने के लिए, विलय करने वाला यूओपी डालने से एक संपूर्ण समस्या/नाम बदलें चक्र होता है जिसके दौरान कोई अन्य यूओएस आवंटित नहीं किया जा सकता है। लेकिन कम 8/निम्न 16 के लिए, विलय करने वाला यूओपी "प्रवाह का हिस्सा" है, इसलिए जाहिर है कि यह अतिरिक्त फ्रंट-एंड थ्रूपूट दंड का कारण किसी मुद्दे/नामकरण चक्र में 4 स्लॉट में से एक को लेने से परे नहीं करता है।

Ivybridge में (या कम से कम Haswell), इंटेल आंशिक-रजिस्टर low8 और low16 रजिस्टरों के लिए नाम बदलने गिरा दिया, (एएच/बिहार/सीएच/DH) केवल high8 रजिस्टरों के लिए यह ध्यान में रखते हुए। उच्च 8 रजिस्टरों को पढ़ने में अतिरिक्त विलंबता है। इसके अलावा, setcc al में रैक्स के पुराने मूल्य पर झूठी निर्भरता है, नेहलेम और पहले (और शायद सैंडब्रिज) के विपरीत। विवरण के लिए this HSW/SKL partial-register performance Q&A देखें।

(मैं पहले से दावा किया है कि Haswell कोई UOP साथ एएच मर्ज कर सकते हैं, लेकिन यह सच नहीं है और नहीं क्या Agner कोहरा का मार्गदर्शक कहता है। मैं भी जल्दी से स्किम्ड और दुर्भाग्य से टिप्पणियां और अन्य पदों के बहुत सारे में मेरी गलत समझ दोहराया।)

एएमडी सीपीयू, और इंटेल सिल्वरमॉन्ट, आंशिक reg (झंडे के अलावा) का नाम नहीं बदलते हैं, इसलिए mov al, [mem] में ईएक्स के पुराने मूल्य पर झूठी निर्भरता है। (उल्टा कोई आंशिक-reg मंदी विलय जब पूर्ण reg बाद में पढ़ने है।)


आम तौर पर, inc के बजाय add केवल समय एएमडी पर अपने कोड तेजी से कर देगा या मुख्यधारा इंटेल है जब आपके कोड वास्तव में निर्भर करता है inc के डॉट-टच-सीएफ व्यवहार पर नहीं। यानी आमतौर पर add केवल तभी मदद करता है जब यह आपके कोड को तोड़ देगा, लेकिन ऊपर उल्लिखित shl नोट करें, जहां निर्देश झंडे को पढ़ता है लेकिन आमतौर पर आपका कोड उस परवाह नहीं करता है, इसलिए यह एक झूठी निर्भरता है।

आप कर तो वास्तव में सीएफ असंशोधित छोड़ना चाहते हैं, पूर्व SNB-परिवार सीपीयू आंशिक-ध्वज स्टालों के साथ गंभीर समस्या है, लेकिन SNB-परिवार पर सीपीयू आंशिक झंडे विलय होने के भूमि के ऊपर बहुत कम है, इसलिए कुछ सीरोलिंग के साथ, उन CPU को लक्षित करते समय लूप स्थिति के हिस्से के रूप में inc या dec का उपयोग करना सबसे अच्छा हो सकता है। (विवरण के लिए, BigInteger adc क्यू & ए मैंने पहले लिंक किया था) देखें। lea का प्रयोग करने के लिए उपयोगी हो सकता है, अगर आपको परिणाम पर शाखा की आवश्यकता नहीं है, तो झंडे को प्रभावित किए बिना अंकगणित करने के लिए।

+3

हालांकि दिलचस्प भी है, परिवर्तनीय शिफ्ट कोर 2 पर वापस 1μop और एकल चक्र के रूप में प्रयोग किया जाता था। इंटेल सामान्य 2 ऑपरेंड/μop नियम को असंभव लगता है, इसलिए मुझे आश्चर्य है कि यह कैसे काम करता है .. और उन्होंने इसे क्यों मार दिया – harold

+0

गोदबॉल्ट ने अभी आईसीसी 16 और 17 जोड़ा है और वे अभी भी 'inc's –

+0

@harold उत्सर्जित करते हैं: कोर 2 पर परीक्षण से पता चलता है कि 'shl reg, cl' लगभग 0.5 प्रति घड़ी के थ्रूपुट के साथ चला सकता है, यहां तक ​​कि ध्वज डिब्बे तोड़ने के लिए कुछ भी नहीं। तो यह 3-इनपुट यूओपी नहीं है। मुझे संदेह है कि यह 'cl' शून्य/शून्य-शून्य होने पर अनुमान लगाता है, लेकिन आईडीके यह और कैसे काम कर सकता है। शायद कुछ सुपर-अजीब जो एसएनबी परिवर्तनों के साथ असंगत था। हम्म, एसएनबी एक पीआरएफ में स्विच किया, लेकिन मुझे आश्चर्य है कि झंडे पूर्णांक रजिस्टर फ़ाइल प्रविष्टियों का उपयोग करते हैं? मुझे आश्चर्य नहीं होगा अगर आरओबी में झंडे के मूल्य अभी भी सही हैं, क्योंकि वहां कई बिट्स नहीं हैं। –

2

निर्देशों के सीपीयू कार्यान्वयन के आधार पर, आंशिक रजिस्टर अपडेट स्टॉल का कारण बन सकता है। Agner Fog's optimization guide, page 62 को,

ऐतिहासिक कारणों अनुसार, INC और DEC निर्देश, अपरिवर्तित झंडा कैरी छोड़ जबकि अन्य अंकगणित झंडे को लिखा जाता है। यह झंडे के पिछले मूल्य पर झूठी निर्भरता का कारण बनता है और एक अतिरिक्त μop खर्च करता है। इन समस्याओं से बचने के लिए, यह अनुशंसा की जाती है कि आप ADD और INC और DEC के बजाय हमेशा उपयोग करें। उदाहरण के लिए, INC EAX को ADD EAX,1 द्वारा प्रतिस्थापित किया जाना चाहिए।

"आंशिक झंडे स्टाल" पर पृष्ठ 83 और "आंशिक झंडे स्टॉल" पर पृष्ठ 100 भी देखें।

+3

यह पेंटियम 4 अध्याय से है। पी 4 ने पी 6 डी (पीपीआरओ/पीआईआईआई) जैसे अलग-अलग ध्वज बिट्स का नाम बदलने के लिए हार्डवेयर को लागू करने के बजाय 'inc' के बजाय 'inc' के बजाय 'r32, 1'' में बदलने के लिए सभी सॉफ़्टवेयर को बदलने का प्रयास किया। यह कोड के लिए प्रासंगिक नहीं है जो पी 4 पर नहीं चलेगा, क्योंकि अन्य सीपीयू इसे हार्डवेयर में संभालते हैं। –

+2

इसके अलावा, यह एक झूठी निर्भरता है। पी 4 में आंशिक-फ्लैग स्टॉल नहीं हैं, क्योंकि इसे कभी भी विभिन्न हिस्सों में बदलावों को मर्ज करना नहीं पड़ता है। इसके बजाए, प्रत्येक आंशिक-झंडा संशोधित निर्देश पुराने झंडे पर निर्भरता है। –

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

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