2016-10-19 5 views
5

शायद यह सब सूक्ष्म- लेकिन नैनोप्टाइमाइजेशन के बारे में भी नहीं है, लेकिन विषय मुझे रूचि देता है और मैं जानना चाहता हूं कि लंबे समय में गैर देशी पंजीकरण आकारों का उपयोग करते समय कोई दंड है या नहीं?लांग मोड में 64/32-बिट रजिस्टरों का उपयोग करते समय कोई दंड हो सकता है?

मैंने विभिन्न स्रोतों से सीखा है, आंशिक रजिस्टर अपडेट (जैसे axeax के बजाय) eflags स्टॉल और प्रदर्शन को कम कर सकता है। लेकिन मुझे लंबे मोड के बारे में निश्चित नहीं है। इस प्रोसेसर ऑपरेशन मोड के लिए रजिस्टर आकार को देशी माना जाता है? x86-64 अभी भी x86 आर्किटेक्चर के लिए एक्सटेंशन हैं, इस प्रकार मेरा मानना ​​है कि 32 बिट अभी भी मूल हैं। या मैं गलत हूँ?

उदाहरण के लिए, निर्देश

sub eax, r14d 

या

sub rax, r14 

की तरह एक ही आकार है, लेकिन किसी भी दंड जब उन दोनों में से किसी का उपयोग कर वहाँ हो सकता है? क्या नीचे दिए गए निर्देशों में पंजीकरण के आकार को मिलाते समय कोई दंड हो सकता है? जब 32 और लगातार निर्देश में 64-बिट रजिस्टर आकार मिश्रण (उच्च DWORD संभालने सभी मामलों में शून्य है)

sub ecx, eax 
sub r14, rax 
+0

16-बिट एक्सेस के लिए दंड हैं। 32-बिट रजिस्टरों का उपयोग और आर 8-आर 15 से परहेज करना ठीक है और वास्तव में अक्सर छोटे कोड आकार की ओर जाता है। –

+4

32 बिट रजिस्टर को लिखने से शीर्ष 32 बिट्स स्वचालित रूप से साफ़ हो जाएंगे, इसलिए आंशिक अद्यतन समस्या से बचा जाता है। – Jester

+0

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

उत्तर

8

वहाँ किसी भी दंड दिए जा सकते?

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 देखें, और इस सब के बारे में अधिक जानकारी के लिए टैग विकि में अन्य लिंक।

+0

बहुत बहुत धन्यवाद –

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