2010-11-20 4 views
20

लिनक्स कर्नेल lock; addl $0,0(%%esp) लिखने की बाधा के रूप में उपयोग करता है, जबकि आरई 2 लाइब्रेरी xchgl (%0),%0 लिखने की बाधा के रूप में उपयोग करती है। क्या अंतर है और कौन सा बेहतर है?x86 पर एक बेहतर लेखन बाधा कौन सा है: लॉक + एडीएल या xchgl?

क्या x86 को पढ़ने के बाधा निर्देशों की भी आवश्यकता है? आरई 2 अपने पढ़ने के बाधा समारोह को x86 पर नो-ऑप के रूप में परिभाषित करता है जबकि लिनक्स इसे lfence या एस-एसई 2 के आधार पर परिभाषित करता है या नहीं। lfence कब आवश्यक है?

उत्तर

7

"लॉक; addl $ 0,0 (%% esp)" अगर हम 0% लॉक वैरिएबल (%% esp) पते पर परीक्षण करते हैं तो तेज़ होता है। हम चर लॉक करने के लिए 0 मूल्य जोड़ने क्योंकि और शून्य झंडा 1 पर सेट है, तो पते पर चर का ताला मूल्य (%% esp) है 0.

lfence इंटेल डेटापत्रक से:

निष्पादित पर एक सीरियलाइजिंग ऑपरेशन सभी लोड-टू-मेमोरी निर्देश जो एलएफएनसीई निर्देश से पहले जारी किए गए थे। यह serializing आपरेशन की गारंटी देता है कि हर लोड अनुदेश कि कार्यक्रम क्रम में पहले आता है LFENCE अनुदेश विश्व स्तर पर दिख रहा है किसी भी लोड अनुदेश कि LFENCE अनुदेश इस प्रकार से पहले विश्व स्तर पर दिख रहा है।

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

संपादित करें:

तो इन दोनों निर्देश के बीच मुख्य अंतर यह है कि xchgl अनुदेश सशर्त झंडे पर कोई असर नहीं होगा। निश्चित रूप से हम लॉक cmpxchg निर्देश के साथ ताला परिवर्तनीय स्थिति का परीक्षण कर सकते हैं लेकिन यह लॉक के साथ अभी भी अधिक जटिल है $ 0 निर्देश जोड़ें।

+1

अगर मैं साझा मेमोरी को लिखता हूं और 'लॉक' कहता हूं; addl $ 0,0 (%% esp) 'या 'sfence', क्या मुझे स्मृति पढ़ने से पहले अन्य प्रक्रिया/धागे में' lfence' को कॉल करने की आवश्यकता है? या क्या लॉक/स्फेन्स निर्देश स्वयं ही गारंटी देता है कि अन्य सीपीयू डेटा देखते हैं? – Hongli

+2

हां, उपसर्ग गारंटी लॉक करें कि निर्देश का परिणाम तुरंत ग्लोबली दिखाई देता है। –

+1

मान लीजिए कि सीपीयू एसएसई का समर्थन करता है लेकिन एसएसई 2 नहीं। मैं 'sfence' का उपयोग करता हूं लेकिन' lfence' का उपयोग नहीं कर सकता। क्या मुझे 'लॉक का उपयोग करने की ज़रूरत है; रीड बाrier के रूप में जोड़ें, या क्या मैं एक पढ़ने बाधा का उपयोग नहीं कर सकता? – Hongli

3

lock; addl और xchgl का महत्वपूर्ण हिस्सा lock उपसर्ग है। यह xchgl के लिए निहित है। दोनों के बीच वास्तव में कोई अंतर नहीं है। मैं देखता हूं कि वे कैसे छोटे (बाइट्स में) को इकट्ठा करते हैं और चुनते हैं क्योंकि यह आमतौर पर x86 पर समकक्ष संचालन के लिए तेज़ है (इसलिए xorl eax,eax जैसे चालें

एसएसई 2 की उपस्थिति शायद वास्तविक स्थिति के लिए एक प्रॉक्सी है जो अंततः cpuid का एक कार्य है। यह शायद पता चला है कि एसएसई 2 lfence के अस्तित्व का तात्पर्य है और एसएसई 2 की उपलब्धता को बूट पर चेक/कैश किया गया था। lfence उपलब्ध होने पर आवश्यक है।

+4

निर्देश 'lfence' एसएसई 2 निर्देश सेट का हिस्सा है। यह प्रॉक्सी नहीं है। –

9

IA32 मैनुअल से हवाला देते हुए (खंड 3 ए, अध्याय 8.2: स्मृति आदेश):

लिखने-वापस संचित करने योग्य के रूप में परिभाषित स्मृति क्षेत्रों के लिए एक एकल प्रोसेसर प्रणाली में, स्मृति आदेश मॉडल का अनुसरण का सम्मान करता है सिद्धांतों [..पढ़ता]

  • पुस्तकें दूसरे के साथ पुनर्क्रमित नहीं कर रहे हैं
  • लिखता बड़े पढ़ता
  • स्मृति को लिखता अन्य लेखन के साथ पुनर्क्रमित नहीं कर रहे हैं, CLFLUSH के साथ निष्पादित
    • राईट के अपवाद के साथ साथ पुनर्क्रमित नहीं कर रहे हैं निर्देश
    • गैर-अस्थायी चाल निर्देशों ([यहां निर्देशों की सूची] के साथ निष्पादित स्ट्रीमिंग स्टोर्स (लिखते हैं))
    • स्ट्रिंग ऑपरेशंस (से ई धारा 8.2.4.1)
  • रीड को अलग-अलग स्थानों पर पुराने लिखने के साथ पुन: व्यवस्थित किया जा सकता है लेकिन पुराने स्थान के साथ समान स्थान पर नहीं लिखा जाता है।
  • पढ़ता है या राईट आई/ओ निर्देश, बंद कर दिया निर्देश, या serializing निर्देश
  • साथ पुनर्क्रमित नहीं किया जा सकता पुस्तकें पारित नहीं हो सकता LFENCE और MFENCE निर्देश
  • लिखता SFENCE और MFENCE निर्देश

नोट पारित नहीं हो सकता : "एक एकल प्रोसेसर सिस्टम में" थोड़ा भ्रामक है। प्रत्येक नियम (लॉजिकल) प्रोसेसर के लिए व्यक्तिगत रूप से समान नियम होते हैं; मैनुअल कई प्रोसेसर के बीच अतिरिक्त ऑर्डरिंग नियमों का वर्णन करने के लिए चला जाता है। यह प्रश्न से संबंधित के बारे में केवल थोड़ा कि

  • बंद निर्देश कुल आदेश है।

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

इसके अलावा, लिखने वाली मेमोरी में, पढ़े कभी भी पुन: व्यवस्थित नहीं होते हैं, इसलिए पढ़ने की बाधाओं की कोई आवश्यकता नहीं है। हालिया x86 प्रोसेसर में स्ट्रीमिंग स्टोर्स और लिखने-संयुक्त मेमोरी (आमतौर पर मैप किए गए ग्राफिक्स मेमोरी के लिए उपयोग किया जाता है) के लिए एक कमजोर स्मृति स्थिरता मॉडल है। यही वह जगह है जहां विभिन्न fence निर्देश खेल में आते हैं; वे किसी भी अन्य मेमोरी प्रकार के लिए जरूरी नहीं हैं, लेकिन लिनक्स कर्नेल में कुछ ड्राइवर लिखने-संयुक्त मेमोरी से निपटते हैं, इसलिए उन्होंने इस तरह अपने पढ़ने-बाधा को परिभाषित किया है। मॉडल प्रति मेमोरी प्रकार ऑर्डर करने की सूची वॉल्यूम में धारा 11.3.1 में है। आईए -32 मैनुअल के 3 ए। लघु संस्करण: लिखें-थ्रू, लिखें-बैक और लिखें-संरक्षित सट्टा पढ़ने (ऊपर वर्णित नियमों का पालन करने) की अनुमति दें, अप्राप्य और मजबूत असुरक्षित मेमोरी में मजबूत ऑर्डर गारंटी है (कोई प्रोसेसर रीडरिंग नहीं, पढ़ता/लिखता है तुरंत एमएमआईओ के लिए उपयोग किया जाता है) और लिखें संयुक्त मेमोरी में कमजोर ऑर्डरिंग है (यानी आराम से आदेश देने वाले नियम जिन्हें बाड़ की आवश्यकता है)।

4

अन्य उत्तरों के विपरीत, हॉटस्पॉट देवों ने पाया कि शून्य ऑफसेट के साथ lock; addl $0,0(%%esp) इष्टतम नहीं हो सकता है, कुछ प्रोसेसर पर यह introduce false data dependencies कर सकता है; संबंधित jdk bug

एक अलग ऑफसेट के साथ एक स्टैक स्थान को छूने से कुछ परिस्थितियों में प्रदर्शन में सुधार हो सकता है।

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