मैंने हमेशा सोचा है कि प्रोसेसर 32 रजिस्टरों पर क्यों रुके। यह मशीन का अब तक का सबसे तेज़ टुकड़ा है, क्यों न केवल अधिक रजिस्टरों के साथ बड़ा प्रोसेसर बनाया जाए? कि कम RAM पर जा रहा मतलब नहीं होगा?
मैंने हमेशा सोचा है कि प्रोसेसर 32 रजिस्टरों पर क्यों रुके। यह मशीन का अब तक का सबसे तेज़ टुकड़ा है, क्यों न केवल अधिक रजिस्टरों के साथ बड़ा प्रोसेसर बनाया जाए? कि कम RAM पर जा रहा मतलब नहीं होगा?
जवाबों:
सबसे पहले, सभी प्रोसेसर आर्किटेक्चर 32 रजिस्टरों पर नहीं रुके। लगभग सभी RISC आर्किटेक्चर जिनके पास निर्देश सेट में 32 रजिस्टर हैं वास्तव में 32 पूर्णांक रजिस्टर और 32 अधिक फ़्लोटिंग पॉइंट रजिस्टर (इसलिए 64) हैं। (फ़्लोटिंग पॉइंट "ऐड" पूर्णांक "ऐड" की तुलना में विभिन्न रजिस्टरों का उपयोग करता है।) स्पार्क आर्किटेक्चर में रजिस्टर विंडोज़ हैं। SPARC पर आप एक बार में केवल 32 पूर्णांक रजिस्टरों का उपयोग कर सकते हैं, लेकिन रजिस्टर एक स्टैक की तरह काम करते हैं और आप एक बार में 16 रजिस्टरों को पुश और पॉप कर सकते हैं। HP / Intel के इटेनियम आर्किटेक्चर में इंस्ट्रक्शन सेट में 128 पूर्णांक और 128 फ्लोटिंग पॉइंट रजिस्टर थे। एनवीडिया, एएमडी, इंटेल, एआरएम और इमेजिनेशन टेक्नोलॉजीज से आधुनिक जीपीयू, सभी अपने रजिस्टर फाइलों में बड़े पैमाने पर रजिस्टरों को उजागर करते हैं। (मुझे पता है कि यह एनवीडिया और इंटेल आर्किटेक्चर का सच है, मैं एएमडी, एआरएम और इमेजिनेशन इंस्ट्रक्शन सेट्स से बहुत परिचित नहीं हूं, लेकिन मुझे लगता है कि रजिस्टर फाइलें भी बड़ी हैं।)
दूसरा, अधिकांश आधुनिक माइक्रोप्रोसेसर संसाधनों के पुन: उपयोग की आवश्यकता के कारण अनावश्यक क्रमांकन को समाप्त करने के लिए रजिस्टर का नामकरण लागू करते हैं, इसलिए अंतर्निहित भौतिक रजिस्टर फाइलें कुछ मशीनों पर बड़ी (96, 128 या 192 रजिस्टर) हो सकती हैं। यह (और डायनामिक शेड्यूलिंग) कुछ को समाप्त कर देती है। संकलक को एक बड़ा रजिस्टर फ़ाइल प्रदान करते हुए कंपाइलर के लिए इतने सारे अनूठे रजिस्टर नाम उत्पन्न करने की आवश्यकता है।
निर्देश सेट में उजागर होने वाले रजिस्टरों की संख्या को और बढ़ाना मुश्किल हो सकता है दो कारण हैं। सबसे पहले, आपको प्रत्येक निर्देश में रजिस्टर पहचानकर्ताओं को निर्दिष्ट करने में सक्षम होना चाहिए। 32 रजिस्टरों के लिए 5 बिट रजिस्टर निर्दिष्टकर्ता की आवश्यकता होती है, इसलिए 3-एड्रेस निर्देश (RISC आर्किटेक्चर पर आम) 32 में से 15 निर्देश बिट्स को रजिस्टरों को निर्दिष्ट करने के लिए खर्च करते हैं। यदि आपने उसे 6 या 7 बिट तक बढ़ाया है, तो आपके पास opcodes और स्थिरांक निर्दिष्ट करने के लिए कम जगह होगी। जीपीयू और इटेनियम के बहुत बड़े निर्देश हैं। बड़े निर्देश एक लागत पर आता है: आपको अधिक अनुदेश मेमोरी का उपयोग करने की आवश्यकता है, इसलिए आपका अनुदेश कैश व्यवहार कम आदर्श है।
दूसरा कारण एक्सेस टाइम है। जितना बड़ा आप मेमोरी को धीमा करते हैं, उससे डेटा एक्सेस करना उतना ही आसान होता है। (मूल भौतिकी के संदर्भ में: डेटा 2-आयामी स्थान में संग्रहीत किया जाता है, इसलिए यदि आप बिट्स संग्रहीत कर रहे हैं, तो एक विशिष्ट बिट की औसत दूरी ।) एक रजिस्टर फ़ाइल बस है। छोटी बहु-पोर्टेड मेमोरी, और इसे बड़ा बनाने में आने वाली बाधाओं में से एक यह है कि अंततः आपको बड़े रजिस्टर फ़ाइल को समायोजित करने के लिए अपने मशीन को धीमा करना शुरू करना होगा। आमतौर पर कुल प्रदर्शन के मामले में यह हार है। O ( √)
रजिस्टर की संख्या को सीमित करने के लिए सिर्फ दो और कारण:
बहुत सारे कोड में बहुत सारे मेमोरी एक्सेस होते हैं (30% एक विशिष्ट आंकड़ा है)। उसमें से, आमतौर पर लगभग 2 / 3rds पढ़े जाते हैं और 1 / 3rds को लिखा जाता है। यह रजिस्टरों से बाहर निकलने के कारण नहीं है जितना कि सरणियों तक पहुंचना, वस्तु सदस्य चर का एक्सेस करना आदि।
यह स्मृति (या डेटा कैशे) में किया जाना है कि कैसे C / C ++ बनाया जाता है (सब कुछ आप एक पॉइंटर प्राप्त कर सकते हैं, जिसके लिए एक पते की आवश्यकता होती है, जिसे संभवतः मेमोरी में संग्रहीत किया जाना चाहिए)। यदि कंपाइलर अनुमान लगा सकता है कि आप पागल अप्रत्यक्ष सूचक चालों का उपयोग करके विली-निली के चर को नहीं लिखेंगे, तो यह उन्हें रजिस्टरों में डाल देगा, और यह फ़ंक्शन चर के लिए बहुत अच्छा काम करता है, लेकिन विश्व स्तर पर सुलभ लोगों के लिए नहीं (आम तौर पर, सब कुछ जो मलोकोस से बाहर आता है ()) क्योंकि वैश्विक स्थिति कैसे बदल जाएगी, इसका अनुमान लगाना असंभव है।
इस वजह से, यह सामान्य नहीं है कि कंपाइलर लगभग 16 से अधिक सामान्य उपयोगों के साथ कुछ भी करने में सक्षम होगा, वैसे भी रजिस्टर करता है। यही कारण है कि सभी लोकप्रिय वास्तुशिल्प के बारे में है कि कई (एआरएम 16 है)।
MIPS और अन्य RISCs में 32 होते हैं क्योंकि यह बहुत मुश्किल नहीं है कि कई रजिस्टर - लागत काफी कम है इसलिए यह "क्यों नहीं?" का एक सा है। 32 से अधिक ज्यादातर बेकार है और रजिस्टर फ़ाइल को एक्सेस करने के लिए अधिक समय तक बनाने का नकारात्मक पक्ष है (रजिस्टर की संख्या में प्रत्येक दोहरीकरण संभावित रूप से मल्टीप्लेक्सर्स की एक अतिरिक्त परत को जोड़ता है जो थोड़ा और देरी जोड़ता है ...)। यह औसत रूप से निर्देशों को थोड़ा लंबा बनाता है - जिसका अर्थ है कि जब निर्देश मेमोरी बैंडविड्थ पर निर्भर करता है तो उस तरह के प्रोग्राम चलाने से आपके अतिरिक्त रजिस्टर वास्तव में आपको धीमा कर रहे हैं!
यदि आपका सीपीयू इन-ऑर्डर है और नाम बदलने का पंजीकरण नहीं करता है और आप प्रति चक्र (3 से अधिक) बहुत सारे ऑपरेशन करने की कोशिश कर रहे हैं, तो सिद्धांत रूप में आपको अधिक रजिस्टरों की आवश्यकता होती है क्योंकि आपके चक्र प्रति ऑप्स की संख्या बढ़ जाती है। यही कारण है कि इटेनियम में बहुत सारे रजिस्टर हैं! लेकिन व्यवहार में, संख्यात्मक-फ़्लोटिंग-पॉइंट या SIMD ओरिएंटेड कोड (जो इटेनियम वास्तव में बहुत अच्छा था) के अलावा, अधिकांश कोड में बहुत सारी मेमोरी रीड / राइट्स और जंप होंगी, जो प्रति चक्र 3 से अधिक ऑप्स के इस सपने को असंभव बनाती हैं (विशेष रूप से सर्वर-उन्मुख सॉफ़्टवेयर जैसे डेटाबेस, कंपाइलर, उच्च-स्तरीय भाषा निष्पादन जैसे जावास्क्रिप्ट, अनुकरण आदि ...)। यह क्या इटेनियम डूब गया।
यह सब गणना और निष्पादन के बीच अंतर के लिए नीचे आता है!
आपको कौन बताता है कि प्रोसेसर में हमेशा 32 रजिस्टर होते हैं? x86 में 8, ARM 32-बिट और x86_64 में 16, IA-64 में 128 और कई अन्य नंबर हैं। आप यहां देख सकते हैं । यहां तक कि MIPS, PPC या किसी भी आर्किटेक्चर के पास निर्देश सेट में 32 सामान्य उद्देश्य रजिस्टर हैं, संख्या 32 से बहुत बड़ी है क्योंकि हमेशा अभी भी ध्वज रजिस्टर (यदि कोई हो), नियंत्रण रजिस्टर ... नामांकित रजिस्टर और हार्डवेयर रजिस्टरों सहित नहीं।
हर चीज की अपनी कीमत होती है। रजिस्टरों की संख्या जितनी अधिक होगी, कार्य स्विचिंग करते समय आपके पास उतना ही अधिक काम होगा, अनुदेश एन्कोडिंग में आपको अधिक स्थान चाहिए। यदि आपके पास कम रजिस्टर है, तो आपको कुछ कंप्यूट-व्यापक कोड में रजिस्टरों की कमी के व्यापार बंद के साथ कॉल करने और फ़ंक्शन से लौटने या कार्यों को स्विच करने पर स्टोर करने और पुनर्स्थापित करने की आवश्यकता नहीं है।
इसके अलावा, रजिस्टर फ़ाइल जितनी बड़ी होगी, वह उतनी ही महंगी और जटिल होगी। SRAM सबसे तेज और सबसे महंगी रैम है इसलिए इसका उपयोग केवल CPU कैश में किया जाता है। लेकिन यह अभी भी बहुत सस्ता है और एक ही क्षमता के साथ रजिस्टर फ़ाइल की तुलना में कम क्षेत्र लेता है।
उदाहरण के लिए, एक विशिष्ट इंटेल प्रोसेसर में "आधिकारिक तौर पर" 16 पूर्णांक और 16 वेक्टर रजिस्टर होते हैं। लेकिन वास्तव में, कई और भी हैं: प्रोसेसर "रजिस्टर नामकरण" का उपयोग करता है। यदि आपके पास एक निर्देश reg3 = reg1 + reg2 है तो आपको एक समस्या होगी यदि reg3 का उपयोग करने वाला कोई अन्य निर्देश अभी तक समाप्त नहीं हुआ है - यदि आप पिछले निर्देश द्वारा पढ़ा गया है तो इससे पहले कि यह reg3 को अधिलेखित कर देता है, तो आप नए निर्देश को निष्पादित नहीं कर सकते।
इसलिए लगभग 160 या इतने ही वास्तविक रजिस्टर हैं। तो ऊपर दिया गया सरल निर्देश "regX = reg1 + reg2" में बदल जाता है, और याद रखें कि regX में reg3 होता है। पुनर्नामित रजिस्टर के बिना, आउट ऑफ ऑर्डर निष्पादन पानी में बिल्कुल मृत हो जाएगा।
मैं एक इलेक्ट्रिकल इंजीनियर नहीं हूं, लेकिन मुझे लगता है कि रजिस्टरों की संख्या को सीमित करने के कारण के लिए एक और संभावना है, रूटिंग है। सीमित संख्या में अंकगणित इकाइयाँ हैं, और उन्हें हर रजिस्टर से इनपुट लेने में सक्षम होना चाहिए, और हर रजिस्टर को आउटपुट देना चाहिए। यह विशेष रूप से सच है जब आपके पास पाइपलाइज्ड प्रोग्राम हैं जो प्रति चक्र कई निर्देशों को निष्पादित कर सकते हैं।
इस के एक सरल संस्करण में जटिलता होगी, जिससे रजिस्टरों की संख्या में वृद्धि हो सकती है, या अन्यथा एक बेहतर जटिलता के साथ सब कुछ रूट करने के लिए कुछ और अधिक जटिल चीज़ों को रूट करने की आवश्यकता होती है।
इवान गोडार्ड की मिल सीपीयू पर कुछ बातचीत देखने से मुझे इस उत्तर का विचार आया। मिल सीपीयू के नवाचार का एक हिस्सा यह है कि आप मनमाने ढंग से रजिस्टर करने के लिए आउटपुट नहीं दे सकते हैं - आउटपुट सभी को एक रजिस्टर स्टैक या "बेल्ट" पर धकेल दिया जाता है, जो इस प्रकार रूटिंग समस्याओं को कम करता है, क्योंकि आप हमेशा जानते हैं कि आउटपुट कहां जाएगा। ध्यान दें कि वे अभी भी अंकगणित इकाइयों को इनपुट रजिस्टर प्राप्त करने के लिए मार्ग की समस्या है।
देखें बेल्ट (9 2) - मिल सीपीयू वास्तुकला समस्या बयान के लिए, और मिल के समाधान।