स्मृति संरेखण का उद्देश्य


196

बेशक मुझे नहीं मिला। मान लें कि आपके पास 1 बाइट की लंबाई वाला मेमोरी शब्द है। आप एक एकल मेमोरी एक्सेस में 4 बाइट लॉन्ग वेरिएबल को अनलॉग्ड एड्रेस पर एक्सेस नहीं कर सकते (अर्थात 4 से विभाज्य नहीं है), क्योंकि यह एड्रेस्ड एड्रेस के मामले में है?


17
कुछ अतिरिक्त Googling करने के बाद मुझे यह शानदार लिंक मिला , जो वास्तव में समस्या को अच्छी तरह से समझाता है।
ark

यह सीखना शुरू करने वाले लोगों के लिए इस छोटे से लेख को देखें: blog.virtualmethodstudio.com/2017/03/memory-alignment-run-fools
darkgaze

3
@ark लिंक टूटा
जॉन जियांग

2
@ जोहानजियांग मुझे लगता है कि मुझे यहाँ नया लिंक मिला: developer.ibm.com/technologies/systems/articles/pa-dalign
ejohnso49

जवाबों:


63

यह कई अंतर्निहित प्रोसेसर की सीमा है। यह आमतौर पर एक कुशल शब्द लाने के बजाय 4 अकुशल एकल बाइट भ्रूण लाकर काम किया जा सकता है, लेकिन कई भाषा विनिर्माताओं ने फैसला किया कि यह आसान होगा कि केवल उन्हें रेखांकित करें और सब कुछ गठबंधन करने के लिए मजबूर करें।

इस लिंक में बहुत अधिक जानकारी है जो ओपी ने खोजी थी।


311

एक आधुनिक प्रोसेसर पर मेमोरी सबसिस्टम मेमोरी की पहुंच को उसके शब्द आकार की बारीकियों और संरेखण तक सीमित रखता है; कई कारणों से यह मामला है।

गति

आधुनिक प्रोसेसर में कैश मेमोरी के कई स्तर होते हैं जिन्हें डेटा के माध्यम से खींचा जाना चाहिए; एकल-बाइट रीडिंग का समर्थन करने से मेमोरी सबसिस्टम थ्रूपुट को निष्पादन इकाई थ्रूपुट (उर्फ सीपीयू-बाउंड) से कसकर बाध्य कर देगा; यह सब इस बात की याद दिलाता है कि हार्ड ड्राइव में समान कारणों से डीआईए द्वारा पीआईओ मोड को कैसे पार किया गया था

सीपीयू हमेशा अपने शब्द आकार (एक 32-बिट प्रोसेसर पर 4 बाइट्स) पर पढ़ता है, इसलिए जब आप एक अनलॉग्ड एड्रेस एक्सेस करते हैं - एक प्रोसेसर पर जो इसका समर्थन करता है - प्रोसेसर कई शब्दों को पढ़ने वाला है। सीपीयू मेमोरी के प्रत्येक शब्द को पढ़ेगा जो आपके अनुरोधित पते को स्ट्राडल करता है। यह अनुरोध किए गए डेटा तक पहुंचने के लिए आवश्यक मेमोरी लेनदेन की संख्या को 2X तक बढ़ाने का कारण बनता है।

इस वजह से, यह चार की तुलना में दो बाइट्स पढ़ने के लिए बहुत आसानी से धीमा हो सकता है। उदाहरण के लिए, मान लें कि आपके पास स्मृति में एक संरचना है जो इस तरह दिखाई देती है:

struct mystruct {
    char c;  // one byte
    int i;   // four bytes
    short s; // two bytes
}

एक 32-बिट प्रोसेसर पर यह सबसे अधिक संभावना है जैसे यहां दिखाया गया है:

संरचना लेआउट

प्रोसेसर इनमें से प्रत्येक सदस्य को एक लेनदेन में पढ़ सकता है।

कहते हैं कि आपके पास संरचना का एक पैक संस्करण था, शायद उस नेटवर्क से जहां यह ट्रांसमिशन दक्षता के लिए पैक किया गया था; यह कुछ इस तरह लग सकता है:

पैक्ड स्ट्रक्चर

पहली बाइट पढ़ना एक ही होना है।

जब आप प्रोसेसर को 0x0005 से 16 बिट्स देने के लिए कहते हैं, तो इसे 0x0004 से एक शब्द पढ़ना होगा और इसे 16-बिट रजिस्टर में रखने के लिए 1 बाइट को छोड़ना होगा; कुछ अतिरिक्त काम, लेकिन अधिकांश इसे एक चक्र में संभाल सकते हैं।

जब आप 0x0001 से 32 बिट्स मांगते हैं तो आपको 2X प्रवर्धन मिलेगा। प्रोसेसर रिजल्ट रजिस्टर में 0x0000 से पढ़ेगा और लेफ्ट 1 बाइट को शिफ्ट करेगा, फिर 0x0004 से फिर से एक अस्थायी रजिस्टर में पढ़ेगा, राइट 3 बाइट को शिफ्ट करेगा, फिर ORरिजल्ट रजिस्टर से।

रेंज

किसी भी दिए गए पते के स्थान के लिए, यदि आर्किटेक्चर यह मान सकता है कि 2 एलएसबी हमेशा 0 (जैसे, 32-बिट मशीन) हैं तो यह 4 गुना अधिक मेमोरी तक पहुंच सकता है (2 सहेजे गए बिट्स 4 अलग-अलग राज्यों का प्रतिनिधित्व कर सकते हैं), या एक ही राशि। झंडे की तरह कुछ के लिए 2 बिट के साथ स्मृति की। एक पते से 2 LSBs लेने से आपको 4-बाइट संरेखण मिलेगा; इसे 4 बाइट्स के स्ट्राइड के रूप में भी जाना जाता है । हर बार जब कोई पता बढ़ाया जाता है तो वह बिट 2 को प्रभावी रूप से बढ़ाता है, बिट 0 नहीं, अर्थात, पिछले 2 बिट्स हमेशा बने रहेंगे 00

यह सिस्टम के भौतिक डिजाइन को भी प्रभावित कर सकता है। यदि एड्रेस बस को 2 कम बिट्स की आवश्यकता है, तो सीपीयू पर 2 कम पिन हो सकते हैं, और सर्किट बोर्ड पर 2 कम निशान हैं।

atomicity

CPU मेमोरी के संरेखित शब्द पर परमाणु रूप से काम कर सकता है, जिसका अर्थ है कि कोई अन्य निर्देश उस ऑपरेशन को बाधित नहीं कर सकता है। यह कई लॉक-फ्री डेटा संरचनाओं और अन्य संगामिति प्रतिमानों के सही संचालन के लिए महत्वपूर्ण है ।

निष्कर्ष

एक प्रोसेसर की मेमोरी प्रणाली यहां वर्णित की तुलना में काफी अधिक जटिल और शामिल है; एक x86 प्रोसेसर वास्तव में कैसे स्मृति को संबोधित करता है, इस पर एक चर्चा (कई प्रोसेसर इसी तरह काम करते हैं)।

मेमोरी संरेखण का पालन करने के कई और लाभ हैं जो आप इस आईबीएम लेख पर पढ़ सकते हैं ।

कंप्यूटर का प्राथमिक उपयोग डेटा को बदलना है। आधुनिक मेमोरी आर्किटेक्चर और तकनीकों को दशकों से अधिक अनुकूलित किया गया है, ताकि अधिक विश्वसनीय तरीके से अधिक डेटा और इन-आउट, और अधिक निष्पादन निष्पादन इकाइयों की सुविधा मिल सके।

बोनस: कैश

एक और एलाइनमेंट-फॉर-परफॉर्मेंस जिसे मैंने पहले अलाउड किया था वह कैशे लाइनों पर संरेखण है जो (उदाहरण के लिए, कुछ सीपीयू) 64B पर हैं।

कैश का लाभ उठाकर कितना प्रदर्शन प्राप्त किया जा सकता है, इसके बारे में अधिक जानकारी के लिए, प्रोसेसर कैश इफेक्ट्स की गैलरी पर एक नज़र डालें ; कैश-लाइन आकारों पर इस प्रश्न से

कुछ प्रकार के प्रोग्राम ऑप्टिमाइज़ेशन के लिए कैश लाइनों की समझ महत्वपूर्ण हो सकती है। उदाहरण के लिए, डेटा का संरेखण यह निर्धारित कर सकता है कि क्या एक ऑपरेशन एक या दो कैश लाइनों को छूता है। जैसा कि हमने ऊपर के उदाहरण में देखा था, इसका मतलब यह आसानी से हो सकता है कि गुमराह मामले में, ऑपरेशन दो बार धीमा होगा।


निम्नलिखित संरचनाओं में xyz के अलग-अलग आकार होते हैं, क्योंकि प्रत्येक सदस्य के नियम से उस पते के साथ शुरू करना होता है जो उसके आकार के गुणकों से होता है और स्ट्रक को उस पते से समाप्त करना पड़ता है जो संरचना के सदस्य के सबसे बड़े आकार के गुणकों से होता है। संरचना x {लघु एस; // 2 बाइट्स और 2 पैडिंग टाइट्स int i; // 4 बाइट्स चार सी; // 1 बाइट्स और 3 पैडिंग बाइट्स लंबे लंबे एल; }; संरचना y {int i; // 4 बाइट्स चार सी; // 1 बाइट्स और 1 पैडिंग बाइट शॉर्ट एस; // 2 बाइट्स}; संरचना z {int i; // 4 बाइट्स शॉर्ट एस; // 2 बाइट्स चार सी; // 1 बाइट्स और 1 पैडिंग बाइट};
गैविन

1
अगर मैं सही तरीके से समझूं, तो इसका कारण यह है कि एक कंप्यूटर एक चरण में एक शब्द नहीं पढ़ सकता है क्योंकि Addesses 30 बिट्स का उपयोग करता है और 32 बिट्स नहीं ??
GetFree

1
@chux हाँ यह सच है, निरपेक्षता कभी नहीं पकड़ती है। 8088 गति और लागत के बीच ट्रेडऑफ का एक दिलचस्प अध्ययन है, यह मूल रूप से 16-बिट 8086 (जिसमें पूर्ण 16-बिट बाहरी बस थी) लेकिन उत्पादन लागत को बचाने के लिए केवल आधा बस-लाइनों के साथ। इस वजह से 8088 को 8086 की तुलना में मेमोरी को एक्सेस करने के लिए घड़ी के चक्र की दो बार जरूरत थी क्योंकि इसे पूरा 16-बिट शब्द प्राप्त करने के लिए दो रीड्स करने थे। दिलचस्प बात यह है कि, 8086 एक चक्र में पढ़े गए 16-बिट को संरेखित करता है, जो बिना पढ़े लिखा होता है। 2. तथ्य यह है कि 8088 में आधे शब्द का बस इस मंदी का सामना करना पड़ा था।
जॉस्पररी

2
@joshperry: थोड़ा सुधार: 8086 एक शब्द-संरेखित 16-बिट चार चक्रों में पढ़ा जा सकता है, जबकि अनप्लग किए गए रीड में आठ लगते हैं । धीमी मेमोरी इंटरफ़ेस की वजह से, 8088-आधारित मशीनों पर निष्पादन का समय आमतौर पर अनुदेशों के साथ हावी होता है। "MOV AX, BX" जैसा एक निर्देश मुख्य रूप से "XCHG AX, BX" की तुलना में एक चक्र तेज है, लेकिन जब तक कि यह पूर्व या निर्देश के बाद नहीं होता है जिसका निष्पादन प्रति कोड बाइट से चार चक्र से अधिक होता है, तो इसे चार चक्रों से अधिक समय लगेगा। निष्पादित। 8086 में, कोड लाने पर कभी-कभी निष्पादन हो सकता है, लेकिन 8088 पर जब तक कोई उपयोग नहीं करता ...
Supercat

1
बहुत सही, @ स्मार्टिन। मैंने चर्चा के इंट्रा-स्ट्रक्चर पर ध्यान केंद्रित करने के लिए उन पैडिंग बाइट्स को आगे बढ़ाया, लेकिन शायद उन्हें शामिल करना बेहतर होगा।
२०:०५ पर joshperry

22

आप कुछ प्रोसेसर के साथ कर सकते हैं ( नेह्म ऐसा कर सकते हैं ), लेकिन पहले सभी मेमोरी एक्सेस 64-बिट (या 32-बिट) लाइन पर संरेखित की गई थी, क्योंकि बस 64 बिट्स चौड़ी है, आपको एक समय में 64 बिट प्राप्त करना था , और 64 बिट के संरेखित 'विखंडू' में इन्हें लाना काफी आसान था।

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

इसलिए, जैसा कि सभी को लगता है कि मेमोरी सस्ती है, उन्होंने सिर्फ कंपाइलर को प्रोसेसर के चंक साइज़ पर डेटा को संरेखित किया ताकि आपका कोड व्यर्थ मेमोरी की कीमत पर तेज़ी से और अधिक कुशलता से चले।


5

मौलिक रूप से, इसका कारण यह है कि मेमोरी बस की कुछ विशिष्ट लंबाई होती है जो मेमोरी साइज की तुलना में बहुत छोटी होती है।

इसलिए, सीपीयू ऑन-चिप एल 1 कैश से बाहर निकलता है, जो कि इन दिनों अक्सर 32 केबी होता है। लेकिन मेमोरी बस जो सीपीयू को एल 1 कैश से जोड़ता है, उसमें कैश लाइन आकार की विशाल छोटी चौड़ाई होगी। यह 128 बिट के आदेश पर होगा ।

इसलिए:

262,144 bits - size of memory
    128 bits - size of bus

गलत तरीके से पहुंच कभी-कभी दो कैश लाइनों को ओवरलैप करेगी, और इसके लिए डेटा प्राप्त करने के लिए पूरी तरह से नए कैश पढ़ने की आवश्यकता होगी। यह भी DRAM के लिए सभी तरह से याद कर सकते हैं।

इसके अलावा, सीपीयू के कुछ हिस्से को इन दो अलग-अलग कैश लाइनों में से एक एकल ऑब्जेक्ट को एक साथ रखने के लिए उसके सिर पर खड़ा होना होगा, जिसमें प्रत्येक के पास डेटा का एक टुकड़ा है। एक पंक्ति में, यह बहुत उच्च क्रम बिट्स में होगा, दूसरे में, बहुत कम क्रम बिट्स।

पूरी तरह से पाइपलाइन में एकीकृत हार्डवेयर समर्पित होगा जो सीपीयू डेटा बस के आवश्यक बिट्स पर संरेखित ऑब्जेक्ट्स को स्थानांतरित करने का काम करता है, लेकिन ऐसे हार्डवेयर में गलत ऑब्जेक्ट्स की कमी हो सकती है, क्योंकि यह संभवतः उन ट्रांजिस्टर का उपयोग करने के लिए सही ढंग से अनुकूलित करने के लिए अधिक समझ में आता है। कार्यक्रम।

किसी भी मामले में, दूसरी मेमोरी जो कभी-कभी आवश्यक होती है, वह पाइपलाइन को धीमा कर देती है, चाहे वह कितना भी विशेष-उद्देश्य वाला हार्डवेयर हो (काल्पनिक और मूर्खतापूर्ण) गलत तरीके से मेमोरी ऑपरेशन को समर्पित करने के लिए समर्पित है।


5

@joshperry ने इस सवाल का शानदार जवाब दिया है। उनके जवाब के अलावा, मेरे पास कुछ संख्याएं हैं जो ग्राफिक रूप से उन प्रभावों को दिखाती हैं जिन्हें वर्णित किया गया था, विशेष रूप से 2X प्रवर्धन। यहां एक Google स्प्रेडशीट का लिंक दिखाया गया है, जिसमें विभिन्न शब्द संरेखण का प्रभाव कैसा दिखता है। इसके अलावा परीक्षण के लिए कोड के साथ एक गिथब जिस्ट का लिंक दिया गया है। परीक्षण कोड को जोनाथन रेंट्ज़्च द्वारा लिखे गए लेख से अनुकूलित किया गया है जिसे @joshperry ने संदर्भित किया है। परीक्षण मैकबुक प्रो पर क्वाड-कोर 2.8 गीगाहर्ट्ज इंटेल कोर आई 7 64-बिट प्रोसेसर और 16 जीबी रैम के साथ चलाए गए थे।

यहां छवि विवरण दर्ज करें


4
क्या करें xऔर yसमन्वय मतलब है?
शुवा

1
क्या पीढ़ी कोर i7? (कोड के लिए लिंक पोस्ट करने के लिए धन्यवाद!)
निक देसुलनिएर्स

2

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


2

यदि आपके पास 32 बिट डेटा बस है, तो मेमोरी से जुड़ी एड्रेस बस एड्रेस लाइन्स A 2 से शुरू होगी , इसलिए एक ही बस साइकल में केवल 32bit एलायंस एड्रेस को एक्सेस किया जा सकता है।

यानी एक - तो अगर एक शब्द भी फैला एक पते संरेखण सीमा 0 16/32 बिट डेटा के लिए या एक 1 शून्य, दो बस चक्र डेटा प्राप्त करना आवश्यक है नहीं 32 बिट डेटा के लिए कर रहे हैं।

कुछ आर्किटेक्चर / इंस्ट्रक्शन सेट अनलगिनेट एक्सेस का समर्थन नहीं करते हैं और इस तरह के प्रयासों पर एक अपवाद उत्पन्न करेंगे, इसलिए अनइंस्टॉल किए गए एक्सेस कोड से उत्पन्न कंपाइलर को न केवल अतिरिक्त बस चक्र की आवश्यकता होती है, बल्कि अतिरिक्त निर्देश भी इसे कम कुशल बनाते हैं।


0

PowerPC पर आप एक अजीब पते से एक पूर्णांक लोड कर सकते हैं जिसमें कोई समस्या नहीं है।

स्पार्क और I86 और (मुझे लगता है) इटानियम जब आप यह कोशिश करते हैं तो हार्डवेयर अपवाद बढ़ाते हैं।

एक 32 बिट लोड बनाम चार 8 बिट लोड सबसे आधुनिक प्रोसेसर पर बहुत अंतर करने जा रहा है। डेटा पहले से कैश में है या नहीं इसका कहीं अधिक प्रभाव पड़ेगा।


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