आधुनिक CPUs पर, add
inc
की तुलना में धीमी कभी नहीं (अप्रत्यक्ष कोड आकार/डिकोड प्रभाव को छोड़कर) है, लेकिन आमतौर पर यह या तो, नहीं तेज है ताकि आप कोड आकार कारणों के लिए 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 ecx
inc
add
के बाद तक प्रतीक्षा करें, भले ही एड के लोड कैश में चूक जाए।) इसे झूठी निर्भरता कहा जाता है। आंशिक ध्वज झंडे के पुराने मूल्य को पढ़कर, सीएफ के अलावा बिट्स को अद्यतन करके, फिर पूर्ण झंडे लिखकर काम लिखता है।
(एएमडी के सहित), अलग झंडे के विभिन्न भागों का नाम बदलने, अन्य सभी बाहर के आदेश 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 के लिए तत्काल चेक किया गया है, लेकिन आउट-ऑफ-ऑर्डर मशीनरी में ध्वज आउटपुट को ट्रैक किए बिना।
चूंकि बिट्स पर लूपिंग आम है, लेकिन हर दूसरे बिट (या किसी अन्य तरफ) पर लूपिंग बहुत असामान्य है, यह एक उचित डिजाइन पसंद की तरह लगता है। यह बताता है कि संकलक test
shr
से सीधे ध्वज परिणामों का उपयोग करने के बजाय शिफ्ट का परिणाम क्यों करते हैं।
अद्यतन: 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
दिसम्बर अनुदेश झंडा कैरी संशोधित नहीं करता है। नतीजतन, एसएचएल ईएक्स, सीएल निर्देश को बाद के पुनरावृत्तियों में तीन माइक्रो-ऑप्स प्रवाह को निष्पादित करने की आवश्यकता है। एसयूबी निर्देश सभी झंडे अद्यतन करेगा। DEC
SUB
के साथ 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
का प्रयोग करने के लिए उपयोगी हो सकता है, अगर आपको परिणाम पर शाखा की आवश्यकता नहीं है, तो झंडे को प्रभावित किए बिना अंकगणित करने के लिए।
@ हंसपैसेंट: यह अब गलत है कि पी 4 अप्रासंगिक है। इंटेल और एएमडी सीपीयू * अलग * अलग-अलग झंडे का नाम बदलते हैं (मुझे लगता है कि वर्चुअलाइज्ड द्वारा इसका मतलब है), इसलिए 'inc/dec' के पास 'EFLAGS' के पुराने मान पर झूठी निर्भरता नहीं है। अनुकूलन मैनुअल बस अद्यतन नहीं किया गया है। –
[आईएनसी से 1 वास्तव में तेजी से जोड़ा गया है? x86] (http://stackoverflow.com/q/13383407/995714) –