वहाँ किसी भी दंड दिए जा सकते?
No, writing to a 32-bit register always zero-extends to the full register, इसलिए x86-64 32 और 64-बिट निर्देश के लिए आंशिक-पंजीकरण दंड से बचाता है।
इस प्रकार मेरा मानना है कि 32 बिट अभी भी मूल हैं।
हाँ, डिफ़ॉल्ट संकार्य आकार सबसे निर्देश (other than PUSH/POP) के लिए 32-बिट है। 64-बिट को डब्ल्यू बिट सेट 1 के साथ एक आरईएक्स उपसर्ग की आवश्यकता है। इसलिए कोड-आकार के कारणों के लिए 32-बिट पसंद करें। यही कारण है कि स्थिर डेटा के पते के लिए कंपेलर mov r32, imm32
का उपयोग करते हैं (क्योंकि डिफ़ॉल्ट कोड-मॉडल के लिए उस कोड और स्थिर डेटा पते की आवश्यकता होती है, वर्चुअल एड्रेस स्पेस के निम्न 2 जीआईबी में)।
यह एएमडी द्वारा डिजाइन विकल्प था। वे दूसरी तरफ से चुन सकते थे, और 32-बिट ऑपरेंड आकार प्राप्त करने के लिए एक उपसर्ग की आवश्यकता थी। चूंकि लंबा मोड एक अलग मोड है, इसलिए x86-64 मशीन कोड x86-32 मशीन कोड से अलग हो सकता है हालांकि यह चाहता है। एएमडी ने मतभेदों को कम करने का फैसला किया ताकि वे डिकोडर्स में जितना संभव हो उतने ट्रांजिस्टर साझा कर सकें। आपका निष्कर्ष सही है, लेकिन आपका तर्क पूरी तरह से फर्जी है।
आंशिक रजिस्टर अद्यतन (eax के बजाय कुल्हाड़ी की तरह) eflags स्टाल के कारण और प्रदर्शन में कमी कर सकते हैं।
आंशिक-ध्वज स्टालों आंशिक-रजिस्टर स्टालों से अलग हैं। उन्हें समान रूप से आंतरिक रूप से संभाला जाता है (EFLAGS के अलग-अलग नामित हिस्सों को एक संशोधित एएक्स के रूप में विलय करना होगा, जिसे ईएक्स के अनमोडिफाइड ऊपरी बाइट्स के साथ विलय किया जाना चाहिए)। लेकिन कोई अन्य का कारण नहीं बनता है।
# partial-reg stall
setcc al # leaves the upper 3 (or 7) bytes unmodified
add edx, eax # reads full EAX. Older CPUs stall while merging
Zeroing EAX ahead of the flag-setting and setcc with xor eax,eax
avoids the partial-register penalty entirely। (कोर 2/नेहलेम पहले के सीपीयू की तुलना में कम चक्रों के लिए स्टाल करता है, लेकिन विलय करने वाले यूओपी डालने के दौरान अभी भी 2 या 3 सी के लिए बंद हो जाता है।मर्जिंग यूओपी डालने के दौरान सैंड्रिब्रिज बिल्कुल नहीं रुकता है)।
(विभिन्न CPUs पर आंशिक पंजीकरण दंड का एक और सारांश: Why doesn't GCC use partial registers?, मूल रूप से वही बात कह रहा है)।
एएमडी बाद में पूर्ण रजिस्टर पढ़ने के दौरान आंशिक-रजिस्टर स्टालों से पीड़ित नहीं है, लेकिन इसके बजाय आंशिक-रजिस्टर लिखता है और पढ़ता है पूर्ण रजिस्टर पर झूठी निर्भरता है। (एएमडी सीपीयू पहली जगह में अलग से उप रजिस्टरों का नाम बदलने नहीं। इंटेल पी 4 और Silvermont/नाइट लैंडिंग उसी तरह कर रहे हैं।)
इंटेल Haswell/Skylake (और शायद Ivybridge) से अलग से al
नाम बदलने नहीं है rax
सभी पर, इसलिए उन्हें कम 8/low16 रजिस्टरों को मर्ज करने की आवश्यकता नहीं है। लेकिन setcc al
पुराने मूल्य पर झूठी निर्भरता है। वे अभी भी ah
का नाम बदलते हैं और विलय करते हैं। (Details on HSW/SKL partial-reg performance।)
# partial flag stall when reading a flag that didn't come from
# the last instruction to write any flags.
clc
# edi and esi = one-past-the-end of dst and src
# ecx = -count
bigInt_add:
mov eax, [esi+ecx*4]
adc [edi+ecx*4], eax # reads CF, partial flag stall on 2nd and later iterations
inc ecx # writes all flags except CF
jl bitInt_add # loop upwards towards zero
इंटेल पूर्व Sandybridge बनाम Sandybridge पर आंशिक-झंडे मुद्दों के बारे में अधिक चर्चा के लिए this Q&A देखें।
भी Agner Fog's microarch pdf देखें, और इस सब के बारे में अधिक जानकारी के लिए x86 टैग विकि में अन्य लिंक।
16-बिट एक्सेस के लिए दंड हैं। 32-बिट रजिस्टरों का उपयोग और आर 8-आर 15 से परहेज करना ठीक है और वास्तव में अक्सर छोटे कोड आकार की ओर जाता है। –
32 बिट रजिस्टर को लिखने से शीर्ष 32 बिट्स स्वचालित रूप से साफ़ हो जाएंगे, इसलिए आंशिक अद्यतन समस्या से बचा जाता है। – Jester
ईएफएलजीएस रजिस्टर आधुनिक प्रोसेसर में भारी वर्चुअलाइज्ड है। सभी रजिस्टरों की तरह हैं। इसके लिए, बहुत से निर्देश इसे संशोधित करते हैं और यह सुपर-स्केलर निष्पादन पर एक बड़ा धब्बा है। आपके कोड से क्या गुम है एक निर्देश है जो वास्तव में * रजिस्टर * का उपयोग करता है। इसलिए प्रोसेसर को इसे अनलॉक करने और आपके द्वारा पोस्ट किए गए कोड को रोकने के लिए कोई अनिवार्य कारण नहीं है। कभी भी इस बारे में कोई राय न लें कि इसे कैसे काम करना चाहिए/काम कर सकता है। असेंबली कोड लिखने का एकमात्र बिंदु सी संकलक की तुलना में तेज़ी से बनाना है। का आकलन करें। –