memory - कैश लाइन कैसे काम करते हैं?




caching line (4)

मैं समझता हूं कि प्रोसेसर डेटा को कैश लाइनों के माध्यम से कैश में लाता है, उदाहरण के लिए, मेरे एटम प्रोसेसर पर - एक समय में लगभग 64 बाइट्स लाता है, जो भी वास्तविक डेटा का आकार पढ़ता है।

मेरा सवाल यह है कि:

कल्पना कीजिए कि आपको स्मृति से एक बाइट पढ़ने की जरूरत है, जिसमें 64 बाइट कैश में लाए जाएंगे?

दो संभावनाएं जो मैं देख सकता हूं वह यह है कि, 64 बाइट ब्याज के बाइट के नीचे निकटतम 64 बाइट सीमा से शुरू होते हैं, या 64 बाइट बाइट के चारों ओर कुछ पूर्व निर्धारित तरीके से फैले होते हैं (उदाहरण के लिए, आधा, आधा, या सभी उपरोक्त)।

जो यह है?


प्रोसेसर में बहु-स्तर के कैश (एल 1, एल 2, एल 3) हो सकते हैं, और ये आकार और गति पर भिन्न होते हैं।

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

शाखा भविष्यवाणी , सीपीयू कैश और प्रतिस्थापन नीतियों के बारे में पढ़ें।

यह एक आसान लक्ष्य नहीं। यदि दिन के अंत में आप जो चाहते हैं वह एक प्रदर्शन परीक्षण है, तो आप Cachegrind जैसे टूल का उपयोग कर सकते हैं। हालांकि, चूंकि यह एक सिमुलेशन है, इसका परिणाम कुछ हद तक भिन्न हो सकता है।


मैं निश्चित रूप से कुछ हार्डवेयर के रूप में कुछ नहीं कह सकता हूं, लेकिन यह आमतौर पर "64 बाइट्स निकटतम 64 बाइट सीमा से शुरू होता है" क्योंकि यह सीपीयू के लिए एक बहुत तेज़ और सरल संचालन है।


यदि कैश लाइन 64 बाइट चौड़े हैं, तो वे स्मृति के ब्लॉक से मेल खाते हैं जो 64 से विभाजित पते पर शुरू होते हैं। किसी भी पते का कम से कम महत्वपूर्ण 6 बिट कैश लाइन में ऑफसेट होता है।

तो किसी दिए गए बाइट के लिए, कैश लाइन जिसे लाया जाना है, पते के कम से कम हस्ताक्षरकर्ता छः बिट्स को साफ़ करके पाया जा सकता है, जो 64 के द्वारा विभाजित निकटतम पते पर घूमने के अनुरूप है।

हालांकि यह हार्डवेयर द्वारा किया जाता है, हम कुछ संदर्भ सी मैक्रो परिभाषाओं का उपयोग करके गणना दिखा सकते हैं:

#define CACHE_BLOCK_BITS 6
#define CACHE_BLOCK_SIZE (1U << CACHE_BLOCK_BITS)  /* 64 */
#define CACHE_BLOCK_MASK (CACHE_BLOCK_SIZE - 1)    /* 63, 0x3F */

/* Which byte offset in its cache block does this address reference? */
#define CACHE_BLOCK_OFFSET(ADDR) ((ADDR) & CACHE_BLOCK_MASK)

/* Address of 64 byte block brought into the cache when ADDR accessed */
#define CACHE_BLOCK_ALIGNED_ADDR(ADDR) ((ADDR) & ~CACHE_BLOCK_MASK)

सबसे पहले मुख्य मेमोरी एक्सेस बहुत महंगा है। वर्तमान में 2GHz CPU (सबसे धीमा एक बार) प्रति सेकंड 2 जी टिक (चक्र) है। एक सीपीयू (वर्चुअल कोर आजकल) प्रति टिक एक बार अपने रजिस्टरों से एक मूल्य प्राप्त कर सकता है। चूंकि वर्चुअल कोर में एकाधिक प्रसंस्करण इकाइयां होती हैं (एएलयू - अंकगणितीय तर्क इकाई, एफपीयू इत्यादि) यदि संभव हो तो यह वास्तव में समानांतर में कुछ निर्देशों को संसाधित कर सकता है।

मुख्य स्मृति की पहुंच लगभग 70ns से 100ns तक (डीडीआर 4 थोड़ा तेज़ है)। इस बार मूल रूप से एल 1, एल 2 और एल 3 कैश को देख रहा है और मेमोरी हिट करने के बजाय (मेमोरी कंट्रोलर को कमांड भेजें, जो इसे मेमोरी बैंक भेजता है), प्रतिक्रिया और इंतजार के लिए प्रतीक्षा करें।

100ns का अर्थ है 200 टिक। तो मूल रूप से यदि कोई प्रोग्राम हमेशा उन कैशों को याद करता है जो प्रत्येक मेमोरी एक्सेस करते हैं, तो CPU इसके समय के बारे में 99,5% खर्च करेगा (अगर यह केवल स्मृति पढ़ता है) मेमोरी के लिए निष्क्रिय इंतजार कर रहा है।

चीजों को गति देने के लिए एल 1, एल 2, एल 3 कैश हैं। वे चिप पर सीधे मेमोरी का उपयोग करते हैं और दिए गए बिट्स को स्टोर करने के लिए एक अलग प्रकार के ट्रांजिस्टर सर्किट का उपयोग करते हैं। इसमें अधिक मेमोरी, अधिक ऊर्जा होती है और मुख्य मेमोरी की तुलना में अधिक महंगा होती है क्योंकि सीपीयू आमतौर पर अधिक उन्नत तकनीक का उपयोग करके उत्पादित होता है और एल 1, एल 2, एल 3 मेमोरी में उत्पादन विफलता में सीपीयू बेकार (दोष) प्रस्तुत करने का मौका होता है। बड़े एल 1, एल 2, एल 3 कैश त्रुटि दर में वृद्धि करते हैं जो उपज को कम करता है जो सीधे आरओआई को कम करता है। तो जब उपलब्ध कैश आकार की बात आती है तो वहां एक बड़ा व्यापार बंद होता है।

(वर्तमान में कोई अधिक एल 1, एल 2, एल 3 कैश बनाता है ताकि कुछ हिस्सों को निष्क्रिय करने में सक्षम हो सकें ताकि वास्तविक उत्पादन दोष कैश मेमोरी एरिया पूरी तरह से सीपीयू दोष को प्रस्तुत कर सके)।

एक समय विचार देने के लिए (स्रोत: कैश और मेमोरी तक पहुंचने के लिए लागत )

  • एल 1 कैश: 1ns से 2ns (2-4 चक्र)
  • एल 2 कैश: 3ns से 5ns (6-10 चक्र)
  • एल 3 कैश: 12ns से 20ns (24-40 चक्र)
  • राम: 60ns (120 चक्र)

चूंकि हम अलग-अलग CPU प्रकारों को मिश्रित करते हैं, ये केवल अनुमान हैं लेकिन एक अच्छा विचार दें कि स्मृति मान प्राप्त होने पर वास्तव में क्या चल रहा है और हमारे पास कुछ कैश परत में हिट या मिस हो सकती है।

तो एक कैश मूल रूप से मेमोरी एक्सेस को गति देता है (60ns बनाम 1ns)।

एक मूल्य प्राप्त करना, इसे फिर से चलाने की संभावना के लिए कैश में संग्रहीत करना उन चरों के लिए अच्छा है जिन्हें अक्सर एक्सेस किया जाता है लेकिन स्मृति प्रतिलिपि संचालन के लिए यह अभी भी धीमा होगा क्योंकि कोई एक मूल्य पढ़ता है, कहीं भी मूल्य लिखता है और कभी भी मूल्य नहीं पढ़ता दोबारा ... कोई कैश हिट नहीं, मृत धीमी (इसके बगल में समानांतर में हो सकता है क्योंकि हमारे पास आदेश निष्पादन से बाहर है)।

यह स्मृति प्रतिलिपि इतनी महत्वपूर्ण है कि इसे गति देने के विभिन्न साधन हैं। शुरुआती दिनों में स्मृति अक्सर सीपीयू के बाहर स्मृति की प्रतिलिपि बनाने में सक्षम थी। इसे मेमोरी कंट्रोलर द्वारा सीधे संभाला गया था, इसलिए एक मेमोरी कॉपी ऑपरेशन ने कैश को प्रदूषित नहीं किया था।

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

तो स्मृति पहुंच पैटर्न का विश्लेषण करके यह स्पष्ट था कि डेटा क्रमशः अक्सर पढ़ा जाता है। एक उच्च संभावना थी कि यदि कोई प्रोग्राम इंडेक्स i पर मान पढ़ता है, तो प्रोग्राम I + 1 मान भी पढ़ेगा। यह संभावना संभावना से थोड़ा अधिक है कि एक ही कार्यक्रम मूल्य i + 2 भी पढ़ेगा और इसी तरह।

तो एक स्मृति पता दिया गया था (और अभी भी है) आगे पढ़ने और अतिरिक्त मूल्य लाने के लिए एक अच्छा विचार था। यही कारण है कि एक बूस्ट मोड है।

बूस्ट मोड में मेमोरी एक्सेस का मतलब है कि एक पता भेज दिया जाता है और एकाधिक मान अनुक्रमिक रूप से भेजते हैं। प्रत्येक अतिरिक्त मूल्य केवल अतिरिक्त 10ns (या यहां तक ​​कि नीचे) लेता है।

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

उदाहरण के लिए 64 बाइट्स की कैश लाइन का अर्थ है कि मेमोरी को आकार में 64bytes के रूप में स्मृति के अलग (गैर-ओवरलैपिंग) ब्लॉक में बांटा गया है। 64bytes का मतलब है कि प्रत्येक ब्लॉक के प्रारंभ पते में सबसे कम छह पता बिट्स हमेशा शून्य होते हैं। तो प्रत्येक बार इन छह शून्य बिट्स को भेजने की आवश्यकता नहीं है पता पता चौड़ाई (स्वागत प्रभाव) की किसी भी संख्या के लिए पता स्थान 64 गुना बढ़ाना आवश्यक नहीं है।

कैश लाइन हल करने की एक और समस्या (आगे पढ़ने के अलावा और पता बस पर छह बिट्स को सहेजना / मुक्त करना) कैश व्यवस्थित करने के तरीके में है। उदाहरण के लिए यदि कैश को 8 बाइट (64 बिट) ब्लॉक (सेल्स) में विभाजित किया जाएगा तो उसे मेमोरी सेल के पते को स्टोर करने की आवश्यकता है, इस कैश सेल के साथ इसके मान भी हैं। यदि पता 64 बिट भी होगा तो इसका मतलब है कि आधे कैश आकार को पते से उपभोग किया जाता है जिसके परिणामस्वरूप 100% का ओवरहेड होता है।

चूंकि एक कैश लाइन 64bytes है और एक सीपीयू 64 बिट - 6 बिट = 58 बिट (शून्य बिट्स को सही तरीके से स्टोर करने की आवश्यकता नहीं है) का मतलब है कि हम 64 बिट्स या 512 बिट्स को 58 बिट (11% ओवरहेड) के ओवरहेड के साथ कैश कर सकते हैं। हकीकत में संग्रहीत पते इससे भी छोटे होते हैं लेकिन स्थिति की जानकारी होती है (जैसे कैश लाइन वैध और सटीक, गंदा है और राम आदि में वापस लिखने की आवश्यकता है)।

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

और अधिक विशेष रूप से जब विभिन्न आभासी कोरों के बीच कैश / मेमोरी एक्सेस सिंक्रनाइज़ करने की बात आती है, प्रति कोर उनकी स्वतंत्र एकाधिक प्रोसेसिंग इकाइयां और आखिर में एक मेनबोर्ड पर कई प्रोसेसर (जिसमें 48 प्रोसेसर और अधिक के बोर्ड होते हैं)।

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

कैश-लाइन (64) का आकार बड़े कैश-लाइनों के बीच एक बुद्धिमान चुने गए व्यापार-बंद को निकट भविष्य में पढ़ने के लिए आखिरी बाइट के लिए असंभव बनाता है, पूर्ण कैश लाइन लाने के लिए अवधि स्मृति से (और इसे वापस लिखने के लिए) और कैश संगठन में ओवरहेड और कैश और मेमोरी एक्सेस के समांतरता।





processor