2009-12-06 21 views
11

मैं अक्सर इस तरह के रूप कोड को देखने जब निम्न, जैसे, स्मृति में एक बड़े बिटमैप का प्रतिनिधित्व:आधुनिक प्रोसेसर पर मेमोरी संरेखण?

size_t width = 1280; 
size_t height = 800; 
size_t bytesPerPixel = 3; 
size_t bytewidth = ((width * bytesPerPixel) + 3) & ~3; /* Aligned to 4 bytes */ 
uint8_t *pixelData = malloc(bytewidth * height); 

(कि, एक बिटमैप स्मृति का एक सन्निहित ब्लॉक के रूप में आवंटित होने एक bytewidth की एक निश्चित संख्या के अनुरूप है

:

pixelData + (bytewidth * y) + (bytesPerPixel * x) 

यह मैं दो प्रश्न की ओर जाता है: बाइट्स, सबसे अधिक 4.)

छवि पर एक बिंदु तो के माध्यम से दिया जाता है

  1. क्या इस तरह के बफर को संरेखित करने से आधुनिक प्रोसेसर पर प्रदर्शन प्रभाव पड़ता है? क्या मुझे संरेखण के बारे में चिंता करना चाहिए, या संकलक इसे संभाल लेंगे?
  2. यदि इसका कोई प्रभाव पड़ता है, तो क्या कोई मुझे विभिन्न प्रोसेसर के लिए आदर्श बाइट संरेखण खोजने के लिए संसाधन पर इंगित कर सकता है?

धन्यवाद।

उत्तर

7

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

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

अन्य प्रोसेसर (उदा। X86) पर, असाइन किए गए पते तक पहुंचने की अनुमति है, लेकिन यह अक्सर एक छिपे प्रदर्शन प्रदर्शन के साथ आता है। मेमोरी लोड/स्टोर अक्सर माइक्रोकोड में लागू होते हैं, और माइक्रोकोड अनियंत्रित पहुंच का पता लगाएगा। आम तौर पर, माइक्रोकोड मेमोरी से उचित 4-बाइट मात्रा लाएगा, लेकिन अगर इसे गठबंधन नहीं किया गया है, तो उसे दो स्मृति से 4-बाइट स्थानों को लाने और दो के उचित बाइट से वांछित 4-बाइट मात्रा को पुनर्निर्माण करना होगा स्थानों। दो स्मृति स्थानों को प्राप्त करना स्पष्ट रूप से एक से धीमा है।

हालांकि यह केवल साधारण लोड और स्टोर के लिए है। कुछ निर्देश, जैसे कि एमएमएक्स या एसएसई निर्देश सेट में, उनके मेमोरी ऑपरेंड को सही तरीके से गठबंधन करने की आवश्यकता होती है। यदि आप उन विशेष निर्देशों का उपयोग करके अनलिखित स्मृति तक पहुंचने का प्रयास करते हैं, तो आपको कुछ अवैध निर्देश अपवाद की तरह दिखाई देगा।

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

यदि आप निर्णय लेते हैं कि आप एकवचन 4-बाइट एक्सेस (3 3-बाइट एक्सेस के विपरीत) में पिक्सल तक पहुंचना चाहते हैं, तो 32-बिट पिक्सेल का उपयोग करना बेहतर होगा और प्रत्येक व्यक्तिगत पिक्सेल को 4- बाइट सीमा। प्रत्येक पंक्ति को 4-बाइट सीमा पर संरेखित करना, लेकिन प्रत्येक पिक्सेल में थोड़ा, यदि कोई हो, प्रभाव नहीं होगा।

आपके कोड के आधार पर, मुझे लगता है कि यह विंडोज बिटमैप फ़ाइल प्रारूप को पढ़ने से संबंधित है - बिटमैप फ़ाइलों को प्रत्येक स्कैनलाइन की लंबाई 4 बाइट्स के एकाधिक की आवश्यकता होती है, इसलिए उस संपत्ति के साथ अपने पिक्सेल डेटा बफर सेट करना उस संपत्ति में जिसे आप केवल पूरे बिटमैप में पढ़ सकते हैं, आपके बफर में झुका हुआ है (बेशक, आपको अभी भी इस तथ्य से निपटना होगा कि स्कैनलाइन को नीचे से नीचे की बजाय नीचे-से-ऊपर संग्रहीत किया जाता है और पिक्सेल डेटा आरजीबी के बजाय बीजीआर है)।यह वास्तव में एक लाभ का अधिक नहीं है, हालांकि - एक समय में एक स्कैनलाइन बिटमैप में पढ़ने के लिए इतना कठिन नहीं है।

1
  • क्या इस तरह के बफर को संरेखित करने से आधुनिक प्रोसेसर पर प्रदर्शन प्रभाव पड़ता है?

हां। उदाहरण के लिए यदि memcpy को सिम निर्देशों (जैसे एमएमएक्स/एसएसई) का उपयोग करके अनुकूलित किया गया है तो कुछ ऑपरेशन गठबंधन स्मृति के साथ तेज होंगे। कुछ आर्किटेक्चर में (प्रोसेसर) निर्देश होते हैं जो विफल होते हैं यदि डेटा गठबंधन नहीं होता है, इस प्रकार कुछ आपकी मशीन पर काम कर सकता है लेकिन किसी अन्य में नहीं।

संरेखित डेटा के साथ आप सीपीयू कैश का बेहतर उपयोग भी करते हैं।

  • क्या मुझे संरेखण के बारे में चिंता करने की ज़रूरत है, या संकलक इसे संभाल लेंगे?

मुझे गतिशील स्मृति का उपयोग करते समय संरेखण के बारे में चिंता करनी चाहिए और संकलक इसे संभाल नहीं सकता (इस टिप्पणी का उत्तर देखें)।

अपने कोड में अन्य सामानों के लिए आपके पास -माइनिंग ध्वज और गठबंधन विशेषता है।

+0

-मललाइन को स्टैक और कोड संरेखण के साथ करना है, यह यहां प्रासंगिक नहीं है। स्मृति को एक 'मॉलोक' के साथ आवंटित किया जाता है जो एक संगत खंड उत्पन्न करता है। यदि पंक्ति की लंबाई 'चौड़ाई * बाइट्सपीरपीक्सेल' 4 (या मूल शब्द आकार, या एक सिम रजिस्टर, या कैश लाइन, अनुप्रयोग के आधार पर विभाजित नहीं है), तो कई पंक्तियों तक पहुंच को असाइन नहीं किया जाएगा। ऊपर संरेखण प्रभावी रूप से प्रत्येक पंक्ति को आवश्यक से थोड़ा लंबा बना रहा है, ताकि वे सभी गठबंधन हो जाएं। संकलक इस अनुकूलन नहीं कर सकता है। लेकिन इस उदाहरण में, अतिरिक्त संरेखण एक नो-ऑप है क्योंकि '1280 * 3% 256 = 0'। – Jed

+0

मुझे -मलिन के बारे में पता है। मैं सामान्य रूप से संरेखण के बारे में बात कर रहा था। – arhuaco

4

हां, संरेखण का आधुनिक पर प्रदर्शन प्रभाव पड़ता है - मान लें x86 - प्रोसेसर। आम तौर पर, प्राकृतिक संरेखण सीमाओं पर डेटा का भार और भंडार होता है; यदि आपको किसी रजिस्टर में 32-बिट मान मिल रहा है, तो यह सबसे तेज़ होगा यदि यह पहले से 32-बिट सीमा पर गठबंधन है। यदि ऐसा नहीं है, तो x86 "आपके लिए इसका ख्याल रखेगा", इस अर्थ में कि सीपीयू अभी भी लोड करेगा, लेकिन इसमें ऐसा करने के लिए चक्रों की एक बड़ी संख्या होगी, क्योंकि इसमें आंतरिक झगड़ा होगा " "पुनः संरेखित करें"।

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

लेकिन विशेष रूप से वर्दी डेटा के बड़े बफर के साथ जो यादृच्छिक रूप से उपयोग किया जाता है और जहां वास्तव में प्रदर्शन वास्तव में महत्वपूर्ण है, जैसा कि ऊपर आपके पिक्सेल बफर में है, डेटा संरचनाओं को गठबंधन रखना अभी भी फायदेमंद हो सकता है।

ध्यान दें कि उदाहरण के मामले में आप ऊपर दिए गए हैं, केवल पिक्सेल डेटा की प्रत्येक "रेखा" गठबंधन है। पिक्सेल स्वयं अभी भी 3 बाइट लंबे हैं और अक्सर "लाइनों" के भीतर असाइन नहीं किए जाते हैं, इसलिए यहां बहुत अधिक लाभ नहीं है। उदाहरण के लिए बनावट प्रारूप हैं, जिनमें प्रति पिक्सेल वास्तविक डेटा के 3 बाइट हैं, और सचमुच डेटा गठबंधन रखने के लिए प्रत्येक पर एक अतिरिक्त बाइट बर्बाद कर देते हैं।

यहाँ कुछ अधिक सामान्य जानकारी है: http://en.wikipedia.org/wiki/Data_structure_alignment

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

1

बफर संरेखण का असर पड़ा है। सवाल यह है: क्या यह एक महत्वपूर्ण प्रभाव है? उत्तर अत्यधिक application specific हो सकता है। आर्किटेक्चर में जो अनौपचारिक पहुंच का मूल रूप से समर्थन नहीं करते हैं- उदाहरण के लिए, 68000 और 68010 (68020 असाइन किए गए पहुंच को जोड़ता है) - यह वास्तव में एक प्रदर्शन और/या रखरखाव समस्या है क्योंकि सीपीयू गलती होगी, या हो सकता है कि एक हैंडलर को अनलिखित पहुंच करने के लिए जाल हो ।

विभिन्न प्रोसेसर के लिए आदर्श संरेखण का अनुमान लगाया जा सकता है: 4-बाइट संरेखण 32-बिट डेटा पथ वाले आर्किटेक्चर के लिए उपयुक्त है। 64-बिट के लिए 8-बाइट संरेखण। हालांकि, एल 1 caching has an effect। कई सीपीयू के लिए यह 64 बाइट्स है हालांकि इसमें भविष्य में कोई संदेह नहीं होगा।

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

आपका उदाहरण अपेक्षाकृत अनोखा है: 3-बाइट तत्वों को व्यक्तिगत रूप से असाइन किए जाने का 50% मौका है (32 बिट्स तक), इसलिए बफर को संरेखित करना कम से कम प्रदर्शन कारणों से व्यर्थ लगता है। हालांकि, पूरी चीज के थोक हस्तांतरण के मामले में, यह पहली पहुंच को अनुकूलित करता है। ध्यान दें कि एक असाइन किए गए पहले बाइट का वीडियो नियंत्रक के स्थानांतरण में प्रदर्शन प्रभाव भी हो सकता है।

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