X86 असेंबली में शून्य पर रजिस्टर सेट करने का सबसे अच्छा तरीका क्या है: xor, mov या?


119

निम्नलिखित सभी निर्देश समान कार्य करते हैं: %eaxशून्य पर सेट । कौन सा तरीका इष्टतम है (सबसे कम मशीन चक्र की आवश्यकता है)?

xorl   %eax, %eax
mov    $0, %eax
andl   $0, %eax


जवाबों:


222

टी एल; डॉ सारांश : xor same, sameहै सभी CPU के लिए सबसे अच्छा विकल्प । किसी अन्य विधि का इस पर कोई लाभ नहीं है, और इसका किसी अन्य पद्धति पर कम से कम कुछ लाभ है। यह इंटेल और एएमडी द्वारा आधिकारिक तौर पर अनुशंसित है, और कंपाइलर क्या करते हैं। 64-बिट मोड में, अभी भी उपयोग करते हैं xor r32, r32, क्योंकि 32-बिट reg लिखने से ऊपरी 32 शून्य होता हैxor r64, r64एक बाइट की बर्बादी है, क्योंकि इसे आरईएक्स उपसर्ग की आवश्यकता है।

इससे भी बदतर, सिल्वरमोंट केवल xor r32,r32डिप-ब्रेकिंग के रूप में पहचानता है , न कि 64-बिट ऑपरेंड-आकार। इस प्रकार तब भी जब REX उपसर्ग अभी भी आवश्यक है क्योंकि आप r8..r15 का उपयोग कर रहे हैं xor r10d,r10d, नहींxor r10,r10

जीपी-पूर्णांक उदाहरण:

xor   eax, eax       ; RAX = 0.  Including AL=0 etc.
xor   r10d, r10d     ; R10 = 0
xor   edx, edx       ; RDX = 0

; small code-size alternative:    cdq    ; zero RDX if EAX is already zero

; SUB-OPTIMAL
xor   rax,rax       ; waste of a REX prefix, and extra slow on Silvermont
xor   r10,r10       ; bad on Silvermont (not dep breaking), same as r10d everywhere else because a REX prefix is still needed for r10d or r10.
mov   eax, 0        ; doesn't touch FLAGS, but not faster and takes more bytes
 and   eax, 0        ; false dependency.  (Microbenchmark experiments might want this)
 sub   eax, eax      ; same as xor on most but not all CPUs; bad on Silvermont for example.

xor   al, al        ; false dep on some CPUs, not a zeroing idiom.  Use xor eax,eax
mov   al, 0         ; only 2 bytes, and probably better than xor al,al *if* you need to leave the rest of EAX/RAX unmodified

एक वेक्टर रजिस्टर को शून्य करना आमतौर पर सबसे अच्छा होता है pxor xmm, xmm। आम तौर पर यही होता है कि gcc क्या करता है (FP निर्देशों के साथ उपयोग करने से पहले)।

xorps xmm, xmmसमझ में आ सकता है। यह एक बाइट से छोटा है pxor, लेकिन xorpsइंटेल pxorनेहेलम पर निष्पादन पोर्ट 5 की आवश्यकता है, जबकि किसी भी पोर्ट (0/1/5) पर चल सकता है। (पूर्णांक और एफपी के बीच नेहेलम के 2 सी बायपास विलंब विलंबता आमतौर पर प्रासंगिक नहीं है, क्योंकि आउट-ऑफ-ऑर्डर निष्पादन आमतौर पर एक नई निर्भरता श्रृंखला की शुरुआत में छिपा सकता है)।

SnB- परिवार के माइक्रोआर्किटेक्चर्स पर, न तो ज़ोर-ज़ीरिंग के स्वाद को एक निष्पादन पोर्ट की भी आवश्यकता है। एएमडी पर, और प्री-नेहेल्म पी 6 / कोर 2 इंटेल, xorpsऔरpxor उसी तरह से संभाला जाता है (वेक्टर-पूर्णांक निर्देश के रूप में)।

128b वेक्टर इंस्ट्रक्शन के AVX वर्जन को रेज के ऊपरी भाग के रूप में अच्छी तरह से उपयोग करते हैं, इसलिए vpxor xmm, xmm, xmmYMM (AVX1 / AVX2) या ZMM (AVX512), या किसी भी अन्य वेक्टर एक्सटेंशन को शून्य करने के लिए एक अच्छा विकल्प है। vpxor ymm, ymm, ymmहालांकि, एनकोडिंग के लिए कोई अतिरिक्त बाइट नहीं लेता है, और इंटेल पर समान चलता है, लेकिन ज़ेन 2 (2 उफ़) से पहले एएमडी पर धीमा। AVX512 ZMM शून्यिंग के लिए अतिरिक्त बाइट्स (EVEX उपसर्ग के लिए) की आवश्यकता होगी, इसलिए XMM या YMM शून्यिंग को प्राथमिकता दी जानी चाहिए।

एक्सएमएम / वाईएमएम / जेडएमएम उदाहरण

    # Good:
 xorps   xmm0, xmm0         ; smallest code size (for non-AVX)
 pxor    xmm0, xmm0         ; costs an extra byte, runs on any port on Nehalem.
 xorps   xmm15, xmm15       ; Needs a REX prefix but that's unavoidable if you need to use high registers without AVX.  Code-size is the only penalty.

   # Good with AVX:
 vpxor xmm0, xmm0, xmm0    ; zeros X/Y/ZMM0
 vpxor xmm15, xmm0, xmm0   ; zeros X/Y/ZMM15, still only 2-byte VEX prefix

#sub-optimal AVX
 vpxor xmm15, xmm15, xmm15  ; 3-byte VEX prefix because of high source reg
 vpxor ymm0, ymm0, ymm0     ; decodes to 2 uops on AMD before Zen2


    # Good with AVX512
 vpxor  xmm15,  xmm0, xmm0     ; zero ZMM15 using an AVX1-encoded instruction (2-byte VEX prefix).
 vpxord xmm30, xmm30, xmm30    ; EVEX is unavoidable when zeroing zmm16..31, but still prefer XMM or YMM for fewer uops on probable future AMD.  May be worth using only high regs to avoid needing vzeroupper in short functions.
    # Good with AVX512 *without* AVX512VL (e.g. KNL / Xeon Phi)
 vpxord zmm30, zmm30, zmm30    ; Without AVX512VL you have to use a 512-bit instruction.

# sub-optimal with AVX512 (even without AVX512VL)
 vpxord  zmm0, zmm0, zmm0      ; EVEX prefix (4 bytes), and a 512-bit uop.  Use AVX1 vpxor xmm0, xmm0, xmm0 even on KNL to save code size.

देखें vxorps-AMD पर जगमग / बुलडोजर / ज़ेन पर xmm रजिस्टर xmm रजिस्टर के साथ ymm की तुलना में तेज़ है? तथा
शूरवीरों के एकल या कुछ ZMM रजिस्टरों को खाली करने का सबसे कुशल तरीका क्या है?

अर्ध-संबंधित: सभी वन बिट्स में __m256 मान सेट करने के लिए सबसे तेज़ तरीका और
सीपीयू रजिस्टर में सभी बिट्स को 1 कुशलता से सेट करने के लिए AVX512 k0..7मास्क रजिस्टर भी शामिल हैं । SSE / AVX vpcmpeqdकई पर डेप-ब्रेकिंग कर रहा है (हालाँकि अभी भी 1s लिखने के लिए यूओपी की आवश्यकता है), लेकिन vpternlogdZMM रेज के लिए AVX512 भी डी-ब्रेकिंग नहीं है। एक लूप के अंदर एक ALU यूओपी के साथ फिर से बनाने के बजाय दूसरे रजिस्टर से कॉपी करने पर विचार करें, विशेष रूप से AVX512 के साथ।

लेकिन ज़ीरिंग सस्ता है: एक लूप के अंदर एक्सएमआर ज़ीरिंग को आमतौर पर कॉपी करना उतना ही अच्छा है, सिवाय कुछ एएमडी सीपीयू (बुलडोजर और ज़ेन) को छोड़कर, जिनके पास वेक्टर रेज के लिए वाई-एलिमिनेशन है, लेकिन फिर भी एक्सोर के लिए ज़ीरो लिखने के लिए एएलओ यूओपी चाहिए -zeroing।


विभिन्न यूरेशों पर एक्सोर जैसे मुहावरों को शून्य करने में क्या खास है

कुछ सीपीयू sub same,sameएक शून्यिंग मुहावरे के रूप में पहचानते हैं xor, लेकिन किसी भी शून्य मुहावरों को पहचानने वाले सभी सीपीयू पहचानते हैंxor । बस xorइसलिए आपको चिंता करने की ज़रूरत नहीं है कि कौन सा सीपीयू पहचानता है कि कौन सा शून्य मुहावरा है।

xor(एक मान्यता प्राप्त शून्य मुहावरे के विपरीत, mov reg, 0) कुछ स्पष्ट और कुछ सूक्ष्म फायदे हैं (सारांश सूची, फिर मैं उन पर विस्तार करूंगा):

  • से छोटा कोड-आकार mov reg,0 । (सभी सीपीयू)
  • बाद के कोड के लिए आंशिक-रजिस्टर दंड से बचा जाता है। (इंटेल पी 6-परिवार और एसएनबी-परिवार)।
  • निष्पादन इकाई का उपयोग नहीं करता, बिजली की बचत करता है और निष्पादन संसाधनों को मुक्त करता है। (इंटेल SnB- परिवार)
  • छोटे यूओपी (तत्काल डेटा नहीं) जरूरत पड़ने पर उधार लेने के लिए पास के निर्देशों के लिए यूओपी कैश-लाइन में कमरा छोड़ देता है। (इंटेल SnB- परिवार)।
  • भौतिक रजिस्टर फ़ाइल में प्रविष्टियों का उपयोग नहीं करता है । (इंटेल एसएनबी-परिवार (और पी 4) कम से कम, संभवतः एएमडी के बाद से वे आरओबी में इंटेल पी 6-परिवार माइक्रोआर्किटेक्चर की तरह रखने के बजाय एक समान पीआरएफ डिजाइन का उपयोग करते हैं।)

छोटे मशीन-कोड आकार (5 के बजाय 2 बाइट्स) हमेशा एक फायदा होता है: उच्चतर कोड घनत्व कम अनुदेश-कैश मिसेज़, और बेहतर अनुदेश लाने के लिए और संभावित रूप से डीकोड बैंडविड्थ की ओर जाता है।


इंटेल एसएनबी-परिवार माइक्रोआर्किटेक्चर पर एक्सोर के लिए एक निष्पादन इकाई का उपयोग नहीं करने का लाभ मामूली है, लेकिन बिजली बचाता है। यह SnB या IvB पर बात करने की अधिक संभावना है, जिसमें केवल 3 ALU निष्पादन पोर्ट हैं। हैसवेल और बाद में 4 निष्पादन पोर्ट हैं जो पूर्णांक ALU निर्देशों को संभाल सकते हैं, जिसमें शामिल हैंmov r32, imm32 शेड्यूलर द्वारा सही निर्णय लेने के साथ, (जो कि हमेशा अभ्यास में नहीं होता है), HSW अभी भी प्रति घड़ी 4 uops बनाए रख सकता है, जब भी उन्हें सभी ALU की आवश्यकता होती है निष्पादन बंदरगाहों।

देखें रजिस्टरों के शून्यीकरण के बारे में एक और सवाल पर मेरा उत्तर कुछ और जानकारी के लिए।

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


एएमडी बुलडोजर-परिवार CPUs पर , mov immediateके रूप में ही EX0 / EX1 पूर्णांक निष्पादन बंदरगाहों पर रन xormov reg,regAGU0 / 1 पर भी चल सकता है, लेकिन यह केवल रजिस्टर कॉपी के लिए है, न कि तुरंत सेट करने के लिए। तो AFAIK, एएमडी पर करने के लिए केवल लाभ xorसे अधिक movछोटे एन्कोडिंग है। यह भौतिक रजिस्टर संसाधनों को भी बचा सकता है, लेकिन मैंने कोई परीक्षण नहीं देखा है।


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

xorहोगा ऊपरी भागों ध्यान केंद्रित किया होने के रूप में रजिस्टर को टैग हां, xor eax, eax/ inc al/ inc eaxसामान्य आंशिक-रजिस्टर दंड है कि पूर्व IVB सीपीयू बचा जाता है। यहां तक ​​कि बिना xor, आईवीबी को केवल एक मर्जिंग यूओपी की आवश्यकता होती है जब उच्च 8 बिट्स ( AH) को संशोधित किया जाता है और फिर पूरे रजिस्टर को पढ़ा जाता है, और हसवेल भी इसे हटा देता है।

एग्नर फॉग के माइक्रो गाइड, पृष्ठ 98 (पेंटियम एम सेक्शन, एसएनबी सहित बाद के वर्गों द्वारा संदर्भित) से:

प्रोसेसर एक रजिस्टर के XOR को शून्य पर सेट करने के साथ ही पहचानता है। रजिस्टर में एक विशेष टैग यह याद रखता है कि रजिस्टर का उच्च भाग शून्य है ताकि EAX = AL। यह टैग एक लूप में भी याद किया जाता है:

    ; Example    7.9. Partial register problem avoided in loop
    xor    eax, eax
    mov    ecx, 100
LL:
    mov    al, [esi]
    mov    [edi], eax    ; No extra uop
    inc    esi
    add    edi, 4
    dec    ecx
    jnz    LL

(pg82 से): प्रोसेसर को याद है कि EAX के ऊपरी 24 बिट्स तब तक शून्य होते हैं जब तक आपको कोई व्यवधान, गलतफहमी, या अन्य सीरियस इवेंट नहीं मिलता।

कि गाइड भी पुष्टि करता है कि की pg82 mov reg, 0है नहीं जल्दी पी 6 पर एक के शून्यीकरण मुहावरा रूप में मान्यता प्राप्त, कम से कम PIII या PM तरह डिजाइन करती है। अगर वे बाद में सीपीयू पर इसका पता लगाने में ट्रांजिस्टर खर्च करते हैं तो मुझे बहुत आश्चर्य होगा।


xorझंडे सेट करता है , जिसका अर्थ है कि आपको परिस्थितियों का परीक्षण करते समय सावधान रहना होगा। चूंकि setccदुर्भाग्य से केवल 8 बिट गंतव्य के साथ उपलब्ध है , इसलिए आपको आमतौर पर आंशिक-पंजीकृत दंड से बचने के लिए ध्यान रखना होगा।

यह अच्छा होता अगर x86-64 ने 16/32/64 बिट के लिए हटाए गए ऑपकोड (जैसे AAM) में से एक को पुन: उत्पन्न किया setcc r/m, साथ ही साथ r / फ़ील्ड के स्रोत-रजिस्टर 3-बिट फ़ील्ड में एन्कोडेड predicate के साथ (रास्ता) कुछ अन्य एकल-ऑपरेंड निर्देश उन्हें ओपोड बिट्स के रूप में उपयोग करते हैं)। लेकिन उन्होंने ऐसा नहीं किया, और वैसे भी x86-32 के लिए मदद नहीं करेगा।

आदर्श रूप से, आपको xorझंडे का उपयोग / सेट करना चाहिए setcc/ पूरा रजिस्टर पढ़ना चाहिए :

...
call  some_func
xor     ecx,ecx    ; zero *before* the test
test    eax,eax
setnz   cl         ; cl = (some_func() != 0)
add     ebx, ecx   ; no partial-register penalty here

यह सभी सीपीयू (कोई स्टॉल, मर्जिंग उप्स, या गलत निर्भरता) पर इष्टतम प्रदर्शन करता है।

जब आप ध्वज-स्थापना निर्देश से पहले xor नहीं चाहते हैं तो चीजें अधिक जटिल होती हैं । उदाहरण के लिए, आप एक स्थिति पर शाखा लगाना चाहते हैं और फिर उसी झंडे से दूसरी शर्त पर सेट करें। उदाहरण के लिए cmp/jle, seteऔर आपके पास या तो एक अतिरिक्त रजिस्टर नहीं है, या आप xorकोड नहीं किए गए कोड से बाहर रखना चाहते हैं।

कोई मान्यता प्राप्त शून्य मुहावरे नहीं हैं जो झंडे को प्रभावित नहीं करते हैं, इसलिए सबसे अच्छा विकल्प लक्ष्य माइक्रोआर्किटेक्चर पर निर्भर करता है। Core2 पर, एक मर्जिंग यूओपी डालने से 2 या 3 चक्र स्टाल हो सकता है। यह SnB पर सस्ता प्रतीत होता है, लेकिन मैंने इसे मापने की कोशिश में ज्यादा समय नहीं लगाया। पुराने इंटेल सीपीयू पर एक महत्वपूर्ण जुर्माना का उपयोग करना mov reg, 0/ setccकरना होगा, और अभी भी नए इंटेल पर कुछ हद तक खराब होगा।

इंटेल पी 6 और एसएनबी परिवारों के लिए उपयोग करना setcc/ movzx r32, r8करना शायद सबसे अच्छा विकल्प है, यदि आप ध्वज-सेटिंग निर्देश के आगे xor-शून्य नहीं कर सकते। यह एक xor-zeroing के बाद परीक्षण को दोहराने से बेहतर होना चाहिए। (यहां तक कि मानते हैं नहीं sahf/ lahfया pushf/ popf)। IvB को समाप्त कर सकते हैं movzx r32, r8(यानी इसे बिना किसी निष्कासन इकाई या विलंबता के साथ रजिस्टर- रीनेमिंग के साथ संभाल सकते हैं , जैसे कि xor-zeroing)। Haswell और बाद में केवल नियमित रूप से खत्म करने movनिर्देश है, तो movzxएक निष्पादन इकाई लेता है और गैर शून्य विलंबता, परीक्षण बन गया है / setcc/ movzxबदतर xor/ परीक्षण / setcc, लेकिन अभी भी कम से कम अच्छा के रूप में के रूप में परीक्षा / mov r,0/ setcc(और ज्यादा बेहतर पुराने CPUs पर)।

एएमडी / पी 4 / सिल्वरमोंट पर पहले शून्य का उपयोग करना setcc/ movzxखराब होना, क्योंकि वे सब-रजिस्टरों के लिए अलग से ट्रैक नहीं करते हैं। रजिस्टर के पुराने मूल्य पर एक गलत चित्रण होगा। का उपयोग करते हुए mov reg, 0/ setccके शून्यीकरण / निर्भरता तोड़ने के लिए शायद सबसे अच्छा विकल्प है जब है xor/ परीक्षण / setccएक विकल्प नहीं है।

बेशक, यदि आपको setcc8 बिट्स से अधिक व्यापक होने के लिए आउटपुट की आवश्यकता नहीं है, तो आपको कुछ भी शून्य करने की आवश्यकता नहीं है। हालाँकि, पी 6 / एसएनबी के अलावा सीपीयू पर गलत निर्भरता से सावधान रहें यदि आप एक रजिस्टर चुनते हैं जो हाल ही में एक लंबी निर्भरता श्रृंखला का हिस्सा था। (और यदि आप किसी फ़ंक्शन को कॉल करते हैं जो किसी फ़ंक्शन को सहेज रहा है / जो कि भाग का उपयोग कर रहा है तो उसे पुनर्स्थापित / पुनर्स्थापित कर सकता है)।


andएक तत्काल शून्य के साथ किसी भी सीपीयू पर पुराने मूल्य के स्वतंत्र के रूप में विशेष-आवरण नहीं है, जिसके बारे में मुझे पता है, इसलिए यह निर्भरता श्रृंखला को नहीं तोड़ता है। इसके कोई फायदे नहीं हैं xorऔर कई नुकसान हैं।

जब आप यह केवल microbenchmarks लिखने के लिए उपयोगी है चाहता हूँ एक विलंबता परीक्षण के हिस्से के रूप निर्भरता, लेकिन शून्यीकरण को और जोड़कर ज्ञात मान बनाना चाहते हैं।


सूक्ष्म विवरण के लिए http://agner.org/optimize/ देखें , जिसमें शून्यिंग मुहावरों को निर्भरता टूटने के रूप में मान्यता प्राप्त है (जैसे sub same,sameकुछ पर है, लेकिन सभी सीपीयू नहीं है, जबकि xor same,sameसभी पर मान्यता प्राप्त है।) movपुराने मूल्य पर निर्भरता श्रृंखला को तोड़ता है । रजिस्टर (स्रोत मूल्य की परवाह किए बिना, शून्य या नहीं, क्योंकि यही movकाम करता है)। xorकेवल विशेष मामले में निर्भरता श्रृंखला को तोड़ता है जहां src और भाग्य एक ही रजिस्टर होते हैं, यही वजह movहै कि विशेष रूप से मान्यता प्राप्त निर्भरता-तोड़ने वालों की सूची से बाहर रखा गया है । (इसके अलावा, क्योंकि इसे शून्य लाभ मुहावरे के रूप में मान्यता नहीं है, अन्य लाभों के साथ जो वहन करता है।)

दिलचस्प बात यह है कि, सबसे पुराना P6 डिज़ाइन ( पेंट्रो III के माध्यम से PPRO ) कोxor -निर्भरता-ब्रेकर के रूप में पहचानना नहीं था , केवल आंशिक-रजिस्टर स्टालों से बचने के प्रयोजनों के लिए एक शून्य मुहावरे के रूप में, इसलिए कुछ मामलों में यह दोनों के लायक था movऔर फिर xor-इस क्रम में डिपो को तोड़ने के लिए और फिर शून्य फिर से + आंतरिक टैग बिट सेट करें कि उच्च बिट शून्य हैं ताकि EAX = AX = AL।

एग्नर फॉग का उदाहरण देखें 6.17। उनके माइक्रोफ़ोन पीडीएफ में। वह कहते हैं कि यह पी 2, पी 3, और यहां तक ​​कि (प्रारंभिक?) पीएम पर भी लागू होता है। लिंक्ड ब्लॉग पोस्ट पर एक टिप्पणी में कहा गया है कि यह केवल Ppro था, जिसकी यह निगरानी थी, लेकिन मैंने कटमई PIII पर परीक्षण किया है, और @Fanael ने एक पेंटियम एम पर परीक्षण किया, और हम दोनों ने पाया कि इसने एक विलंबता के लिए निर्भरता नहीं तोड़ी है -बाउंड imulचेन। यह दुर्भाग्य से, एगनर फॉग के परिणामों की पुष्टि करता है।


टी एल: डॉ:

यदि यह वास्तव में आपके कोड को अच्छा बनाता है या निर्देश बचाता है, तो सुनिश्चित करें movकि झंडे को छूने से बचने के लिए शून्य है , जब तक कि आप कोड आकार के अलावा किसी प्रदर्शन समस्या का परिचय नहीं देते हैं। क्लोबरिंग झंडे से बचना ही उपयोग न करने का एकमात्र समझदार कारण है xor, लेकिन कभी-कभी आप उस चीज़ के आगे xor-शून्य कर सकते हैं जो फ़्लैग सेट करता है यदि आपके पास कोई अतिरिक्त रजिस्टर है।

mov-एजरो आगे से setccविलंबता के लिए बेहतर है movzx reg32, reg8(इंटेल पर छोड़कर जब आप विभिन्न रजिस्टर उठा सकते हैं), लेकिन बदतर कोड आकार।


7
अधिकांश अंकगणितीय निर्देश ओपी आर, एस को एक आदेश के रूप में रजिस्टर आर की सामग्री के लिए प्रतीक्षा करने के लिए सीपीयू के बाहर से मजबूर किया जाता है, रजिस्टर आर के साथ पिछले निर्देशों द्वारा एक लक्ष्य के रूप में भरा जाता है; यह एक डेटा निर्भरता है। मुख्य बिंदु यह है कि इंटेल / एएमडी चिप्स में एक्स -आर, आर का सामना होने पर रजिस्टर आर पर डेटा-वेट-फॉर-डेटा-निर्भरता को तोड़ने के लिए विशेष हार्डवेयर होता है, और जरूरी नहीं कि अन्य रजिस्टर शून्य निर्देश के लिए ऐसा करें। इसका अर्थ है कि XOR निर्देश को तत्काल निष्पादन के लिए निर्धारित किया जा सकता है, और यही कारण है कि Intel / AMD इसका उपयोग करने की सलाह देते हैं।
इरा बैक्सटर

3
@ आईबैक्सटर: हाँ, और बस किसी भी भ्रम से बचने के लिए (क्योंकि मैंने एसओ पर इस गलत धारणा को देखा है), mov reg, srcओओ सीपीयू के लिए डिपो चेन को भी तोड़ता है (भले ही src के इम 332 [mem], या किसी अन्य रजिस्टर की परवाह किए बिना )। अनुकूलन-नियमावली में इस निर्भरता-विच्छेद का उल्लेख नहीं मिलता है क्योंकि यह कोई विशेष मामला नहीं है जो केवल तब होता है जब src और dest एक ही रजिस्टर हो। यह हमेशा उन निर्देशों के लिए होता है जो उनके भाग्य पर निर्भर नहीं करते हैं। ( popcnt/lzcnt/tzcntनियति पर झूठे डिपो होने के इंटेल के कार्यान्वयन को छोड़कर ।)
पीटर कॉर्ड्स

2
@ ज़बोसन: बिना किसी निर्भरता के एक निर्देश का "विलंबता" केवल तभी मायने रखता है जब पाइपलाइन में एक बुलबुला था। यह चलन-उन्मूलन के लिए अच्छा है, लेकिन शून्य निर्देश के लिए शून्य-विलंबता लाभ केवल एक शाखा मिसप्रिंट या आई $ मिस की तरह कुछ के बाद खेलने में आता है, जहां निष्पादन डेटा के तैयार होने के बजाय डिकोड किए गए निर्देशों की प्रतीक्षा कर रहा है। लेकिन हां, चलन-उन्मूलन movमुक्त नहीं करता है , केवल शून्य विलंबता है। "निष्पादन पोर्ट नहीं लेना" भाग आमतौर पर महत्वपूर्ण नहीं है। फ्यूज्ड-डोमेन थ्रूपुट आसानी से अड़चन, जासूसी हो सकता है। मिश्रण में लोड या स्टोर के साथ।
पीटर कॉर्डेस

2
Agner के अनुसार KNL 64-बिट रजिस्टरों की स्वतंत्रता को मान्यता नहीं देता है। तो xor r64, r64बस एक बाइट बर्बाद मत करो। जैसा कि आप कहते हैं कि xor r32, r32विशेष रूप से KNL के साथ सबसे अच्छा विकल्प है। यदि आप और अधिक पढ़ना चाहते हैं, तो इस माइक्रो-मैनुअल में धारा 15.7 "स्वतंत्रता के विशेष मामले" देखें।
जेड बोसोन

3
आह, जहां अच्छा पुराने MIPS, इसके "शून्य रजिस्टर" के साथ जब आपको इसकी आवश्यकता होती है।
हयालसी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.