2013-01-21 25 views
43

के बीच का अंतर लॉक-फ्री डेटा संरचनाओं और समय कोड को कार्यान्वित करते समय संकलक के अनुकूलन को दबाने के लिए अक्सर आवश्यक होता है। आम तौर पर लोग asm volatile का उपयोग क्लॉबर सूची में memory के साथ करते हैं, लेकिन आप कभी-कभी केवल asm volatile या केवल सादा asm क्लोबबरिंग मेमोरी देखते हैं।एएसएम, एएसएम अस्थिर और क्लोबबरिंग मेमोरी

कोड जनरेशन पर विशेष रूप से जीसीसी में इन अलग-अलग बयानों का क्या प्रभाव पड़ता है, क्योंकि यह पोर्टेबल होने की संभावना नहीं है)? ।।

asm (""); // presumably this has no effect on code generation 
asm volatile (""); 
asm ("" ::: "memory"); 
asm volatile ("" ::: "memory"); 
+0

किसी ने अब तक चारों ओर खिलवाड़ किए जाने की भी के करीब लगता है धातु :-) (और कहीं और, @Mysticial एक हास्यास्पद विस्तृत जवाब में दूर लिख रहा है ...) –

उत्तर

39

"Extended Asm" page in the GCC documentation देखें है।

आप asm के बाद कीवर्ड volatile लिख कर हट जाने से एक asm अनुदेश रोका जा सकता है। [...] volatile कीवर्ड इंगित करता है कि निर्देश के महत्वपूर्ण दुष्प्रभाव हैं। यदि यह पहुंच योग्य है तो जीसीसी volatile एएसएम को हटा नहीं देगा।

और

एक asm अनुदेश किसी भी उत्पादन ऑपरेंड के बिना एक अस्थिर asm अनुदेश के समान माना जाएगा।

अपने उदाहरण से कोई भी उत्पादन ऑपरेंड निर्दिष्ट किया है, इसलिए asm और asm volatile रूपों समान रूप से व्यवहार: वे कोड है जो नष्ट नहीं किया जा सकता है में एक बिंदु बनाने के (जब तक यह पहुँच योग्य नहीं साबित हुई है)।

यह कुछ भी करने जैसा नहीं है। एक डमी asm का एक उदाहरण है जो कोड पीढ़ी में परिवर्तन के लिए this question देखें - कि उदाहरण में, कोड है कि एक पाश 1000 बार कोड है जो एक ही बार में लूप के 16 पुनरावृत्तियों की गणना करता है में vectorised हो जाता है दौर चला जाता है, लेकिन लूप के अंदर asm की उपस्थिति ऑप्टिमाइज़ेशन को रोकती है (asm 1000 बार तक पहुंच जाना चाहिए)।

इस कारण जीसीसी नहीं रखने के लिए होगा:

"memory" पीटना जीसीसी मान लेते हैं कि किसी भी स्मृति मनमाने ढंग से किया जा सकता है पढ़ने के लिए या asm ब्लॉक द्वारा लिखित, तो यह भर में लोड होता है या दुकानों को पुन: क्रम से संकलक पाएगा बनाता है असेंबलर निर्देशों में रजिस्टरों में कैश किए गए मेमोरी मान और उस मेमोरी में स्टोर्स या लोड को अनुकूलित नहीं करते हैं।

(यही कारण है कि, हालांकि एक और सीपीयू के संबंध में भार और दुकानों को पुन: क्रम से एक सीपीयू को रोकने नहीं करता है;। आपको लगता है कि के लिए असली स्मृति बाधा निर्देशों की आवश्यकता है)

+0

यह वास्तव में बहुत ही रोचक है, यह महसूस नहीं कर रहा है कि gcc आउटपुट के बिना 'asm' ब्लॉक का व्यवहार करता है क्योंकि अस्थिरता मेरे ज्ञान में एक बड़ा अंतर था। – jleahy

+0

तो 'volatile' = प्रदर्शन-हत्यारा कोई फर्क नहीं पड़ता कि इसका उपयोग किस संदर्भ में किया जाता है (चर या एएसएम)। इसे 'गोटो' कीवर्ड से फ़ाइल करें - केवल जरूरी होने पर ही उपयोग करें। – etherice

8

asm ("") कुछ नहीं करता है (या कम से कम, यह कुछ भी नहीं करना चाहिए है

asm volatile ("") भी करता है कुछ भी नहीं

asm ("" ::: "memory"):

बस संदर्भ के लिए, इन दिलचस्प बदलाव होते रहते हैं एक साधारण कंपाइलर बाड़ है।

asm volatile ("" ::: "memory") AFAIK वही है पिछले के रूप में। volatile कीवर्ड संकलक को बताता है कि इसे इस असेंबली ब्लॉक को स्थानांतरित करने की अनुमति नहीं है। उदाहरण के लिए, यदि यह संकलक निर्णय लेता है कि प्रत्येक आवंटन में इनपुट मान समान हैं तो इसे लूप से बाहर निकाल दिया जा सकता है। मैं वास्तव में निश्चित नहीं हूं कि कंपाइलर किस स्थिति में निर्णय लेगा कि यह असेंबली के बारे में पर्याप्त समझता है कि वह अपने प्लेसमेंट को अनुकूलित करने का प्रयास कर सके, लेकिन volatile कीवर्ड पूरी तरह से दबा देता है। उस ने कहा, अगर मुझे कंपाइलर ने asm कथन को स्थानांतरित करने का प्रयास किया तो मुझे आश्चर्य होगा कि जिसने कोई घोषित इनपुट या आउटपुट नहीं किया था।

संयोग से, volatile भी संकलक अभिव्यक्ति को हटाने से रोकता है अगर यह तय करता है कि उत्पादन मूल्यों अप्रयुक्त कर रहे हैं। यह केवल तभी हो सकता है जब आउटपुट मान हों, इसलिए यह asm ("" ::: "memory") पर लागू नहीं होता है।

+6

मैथ्यू स्लेटरी के जवाब बताते हैं कि 'एएसएम अस्थिर (" ")' नहीं कुछ नहीं कर के रूप में काफी एक ही है, के रूप में यह कर सकते हैं संकलक अनुकूलन पर कठोर प्रभाव पड़ता है। एक ही प्रदर्शन प्रभाव 'एएसएम अस्थिर ("" ::: "स्मृति") 'एक कंपाइलर बाड़ के रूप में उपयोग करने के लिए लागू होगा। – etherice

+0

कंपाइलर असेंबली भाषा को समझ में नहीं आता है! – curiousguy

+1

@curiousguy नहीं है, लेकिन यह समझ में जब एक 'asm' ब्लॉक आदानों/आउटपुट की घोषणा की है, जो संकलक जो पंजीकृत करता है कहता है उस पर निर्भर हैं और कौन से इसे संशोधित है, और इसलिए संकलक कुछ संगणना के आसपास शफ़ल सकता है अगर वे डॉन 'फिर इनपुट/आउटपुट को प्रभावित नहीं करता है। –

1

सिर्फ केविन बल्लार्ड के उत्तर पर पूर्णता के लिए, विजुअल स्टूडियो 2010 _ReadBarrier(), _WriteBarrier() और _ReadWriteBarrier() को ऐसा करने के लिए प्रदान करता है (VS2010 64-बिट ऐप्स के लिए इनलाइन असेंबली की अनुमति नहीं देता है)।

ये कोई निर्देश नहीं उत्पन्न करते हैं लेकिन संकलक के व्यवहार को प्रभावित करते हैं। एक अच्छा उदाहरण here

MemoryBarrier() उत्पन्न करता है lock or DWORD PTR [rsp], 0