2016-06-09 6 views
6

को पार करने वाले असाइन किए गए लोड और स्टोर को मैंने कहीं पढ़ा है कि पेज सीमा के बगल में असाइन किए गए लोड या स्टोर को करने से पहले (उदाहरण के लिए _mm_loadu_si128/_mm_storeu_si128 इंट्रिनिक्स का उपयोग करके), कोड को पहले जांचना चाहिए कि क्या पूरे वेक्टर (इस मामले में 16 बाइट्स) एक ही पृष्ठ से संबंधित है, और यदि नहीं, तो गैर-वेक्टर निर्देशों पर स्विच करें। मैं समझता हूं कि अगर अगला पृष्ठ प्रक्रिया से संबंधित नहीं है तो coredump को रोकने के लिए इसकी आवश्यकता है।एसएसई: पृष्ठ सीमा

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

पर्यावरण: लिनक्स, x86_64, जीसीसी

उत्तर

7

पृष्ठ लाइन विभाजन प्रदर्शन के लिए बुरा कर रहे हैं, लेकिन असंरेखित पहुंच की शुद्धता को प्रभावित नहीं करते। यह सुनिश्चित करने के लिए पर्याप्त है कि आप बफर के अंत से पहले नहीं पढ़ते हैं, जब आप समय से पहले की लंबाई जानते हैं।


शुद्धता के लिए, आप अक्सर जब strlen, जहाँ आपके पाश बंद हो जाता है जब आप एक प्रहरी मान निकालने की तरह कुछ को लागू इसके बारे में चिंता करने की जरूरत है। वह मूल्य आपके वेक्टर के भीतर किसी भी स्थिति में हो सकता है, इसलिए केवल 16 बी असाइन किए गए लोड करने से सरणी के अंत में पढ़ा जाएगा। यदि 0 को समाप्त करना एक पृष्ठ के अंतिम बाइट में है, और अगला पृष्ठ पठनीय नहीं है, और आपका वर्तमान-स्थिति पॉइंटर असाइन नहीं किया गया है, तो 0 बाइट में एक लोड में अपठनीय पृष्ठ से बाइट भी शामिल होंगे, इसलिए यह गलती होगी ।

एक समाधान स्केलर करना है जब तक कि आपका सूचक गठबंधन न हो जाए, फिर गठबंधन वैक्टर लोड करें। एक गठबंधन भार हमेशा एक पृष्ठ से और एक कैश-लाइन से पूरी तरह से आता है। तो भले ही आप स्ट्रिंग के अंत से पहले कुछ बाइट्स पढ़ लेंगे, आपको गलती न होने की गारंटी है। Valgrind इसके बारे में नाखुश हो सकता है, लेकिन मानक लाइब्रेरी strlen कार्यान्वयन इसका उपयोग करते हैं।

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


प्रदर्शन कारणों से पेज-लाइन स्प्लिट से बचने के लायक हो सकता है। भले ही आपको पता है कि आपका src सूचक गलत तरीके से गलत है, हार्डवेयर हार्डवेयर को कैश-लाइन विभाजन को संभालने के लिए अक्सर तेज़ होता है। लेकिन स्काइलेक से पहले, पेज-स्प्लिट में अतिरिक्त ~ 100 सी विलंबता होती है। (Down to 5c in Skylake)। यदि आपके पास एकाधिक पॉइंटर्स हैं जिन्हें अलग-अलग एक दूसरे के सापेक्ष गठबंधन किया जा सकता है, तो आप हमेशा अपने स्रोत को संरेखित करने के लिए प्रस्तावना का उपयोग नहीं कर सकते हैं। (जैसे c[i] = a[i] + b[i], और c गठबंधन है लेकिन b नहीं है।)

उस मामले में, यह एक शाखा उपयोग करने से पहले से और बाद पृष्ठ विभाजन गठबंधन लोड करने के लिए लायक हो सकता है, और उन्हें palignr के साथ गठबंधन।

एक शाखा गलत अनुमान (~ 15 सी) पेज-स्प्लिट विलंबता से सस्ता है, लेकिन सब कुछ देरी (केवल लोड नहीं)। इसलिए यह हार्डवेयर के आधार पर और मेमोरी एक्सेस में गणना के अनुपात के आधार पर इसके लायक हो सकता है।


आप एक समारोह है कि है आमतौर पर संरेखित संकेत के साथ कहा जाता है लिख रहे हैं, यह भावना सिर्फ असंरेखित लोड/दुकान निर्देशों का उपयोग करने के लिए बनाता है। Misalignment का पता लगाने के लिए कोई प्रस्तावना पहले से गठबंधन मामले के लिए अतिरिक्त ओवरहेड है, और आधुनिक हार्डवेयर (नेहलेम और नए) पर, रनटाइम पर गठबंधन करने वाले पते पर असाइन किए गए लोड के पास गठबंधन लोड निर्देशों के समान प्रदर्शन होते हैं। (लेकिन आपको स्मृति निर्देशों के रूप में अन्य निर्देशों में गुना करने के लिए अवांछित लोड के लिए AVX की आवश्यकता है। उदाहरण के लिए vpxor xmm0, xmm1, [rsi])

गलत हस्ताक्षर किए गए इनपुट को संभालने के लिए कोड जोड़कर, आप सामान्य गठबंधन मामले को धीमा करने के लिए सामान्य गठबंधन मामले को धीमा कर रहे हैं। असाइन किए गए लोड/स्टोर्स के लिए फास्ट हार्डवेयर सपोर्ट सॉफ़्टवेयर को कुछ मामलों के लिए हार्डवेयर को छोड़ देता है जहां यह होता है।

(गलत संरेखित आदानों आम हैं, तो यह यह आपके इनपुट सूचक संरेखित करने के लिए, खास तौर पर एक प्रस्तावना का उपयोग करने के लायक है। आप AVX। अनुक्रमिक 32B AVX भार उपयोग कर रहे हैं कैश-लाइन होगा हर दूसरे लोड अलग हो गए।)

Agner Fog's Optimizing Assembly guide अधिक जानकारी के लिए, और टैग विकी में अन्य लिंक देखें।

+0

@ZheyuanLi: हाँ, मुझे उत्सुकता है कि डिजाइन परिवर्तन ने सक्षम किया है। स्काइलेक दो टीएलबी मिस को हल करने के लिए समानांतर में दो पेज-पैदल भी कर सकता है। उन दो तथ्यों को जोड़ा जा सकता है। –

+0

धन्यवाद! मुझे यह भी एहसास नहीं हुआ कि क्रॉस-पेज एक्सेस में ऐसी उच्च लागत हो सकती है। तो यह निश्चित रूप से देखने के लिए कुछ है। –

+1

बीटीडब्लू, वालग्रिंड में विकल्प --partial-loads-ok = yes है जो लोड किए गए डेटा को वेक्टर लोड के कारण "अमान्य पढ़ने" मुद्दों को छुपा सकता है जब लोड किया गया डेटा बफर का पिछला अंत होता है। –

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