मूल रूप से __asm__ __volatile__()
क्या करता है और "memory"
एआरएम आर्किटेक्चर के लिए क्या महत्व है?__asm__ __volatile__ का काम ("":: "स्मृति")
उत्तर
asm volatile("" ::: "memory");
एक कंपाइलर स्तर मेमोरी बाधा बनाता है जो अनुकूलक को मजबूर करता है ताकि बाधा में मेमोरी एक्सेस को फिर से ऑर्डर न किया जा सके।
उदाहरण के लिए, यदि आपको किसी विशिष्ट क्रम में कुछ पता तक पहुंचने की आवश्यकता है (संभवतः क्योंकि स्मृति क्षेत्र वास्तव में स्मृति के बजाए किसी भिन्न डिवाइस द्वारा समर्थित है) तो आपको इसे कंपाइलर को यह बताने में सक्षम होना चाहिए अन्यथा यह केवल दक्षता के लिए अपने कदम अनुकूलित करें।
इस परिदृश्य में मान लें कि आपको पते में एक मूल्य बढ़ाना चाहिए, कुछ पढ़ना चाहिए और आसन्न पते में एक और मूल्य बढ़ाना चाहिए।
int c(int *d, int *e) {
int r;
d[0] += 1;
r = e[0];
d[1] += 1;
return r;
}
समस्या (इस मामले में gcc
) संकलक बेहतर प्रदर्शन प्राप्त करने के लिए यदि आप इसे (-O
) के लिए पूछने के लिए अपनी स्मृति का उपयोग पुनर्व्यवस्थित कर सकते हैं है। शायद नीचे की तरह निर्देश के अनुक्रम को प्रेरित किया:
00000000 <c>:
0: 4603 mov r3, r0
2: c805 ldmia r0, {r0, r2}
4: 3001 adds r0, #1
6: 3201 adds r2, #1
8: 6018 str r0, [r3, #0]
a: 6808 ldr r0, [r1, #0]
c: 605a str r2, [r3, #4]
e: 4770 bx lr
d[0]
और d[1]
के लिए ऊपर मूल्यों एक ही समय में लोड किए गए हैं। आइए मान लें कि यह ऐसा कुछ है जिसे आप टालना चाहते हैं तो आपको संकलक को बताना होगा कि मेमोरी एक्सेस को पुन: व्यवस्थित न करें और asm volatile("" ::: "memory")
का उपयोग करना है।
00000000 <c>:
0: 6802 ldr r2, [r0, #0]
2: 4603 mov r3, r0
4: 3201 adds r2, #1
6: 6002 str r2, [r0, #0]
8: 6808 ldr r0, [r1, #0]
a: 685a ldr r2, [r3, #4]
c: 3201 adds r2, #1
e: 605a str r2, [r3, #4]
10: 4770 bx lr
12: bf00 nop
ऐसा लगता है कि यह केवल समय स्मृति बाधा संकलन है संकलक से बचने के लिए स्मृति तक पहुँचता को पुन: व्यवस्थित करने के लिए के रूप में,:
int c(int *d, int *e) {
int r;
d[0] += 1;
r = e[0];
asm volatile("" ::: "memory");
d[1] += 1;
return r;
}
इसलिए आप जितने चाहें वैसा अपने अनुदेश अनुक्रम मिल जाएगा यह यादों को फ्लश करने या लोड या स्टोर को पूरा करने के लिए प्रतीक्षा करने के लिए कोई अतिरिक्त हार्डवेयर स्तर के निर्देश नहीं रखता है। CPUs अभी भी मेमोरी एक्सेस को पुन: व्यवस्थित कर सकते हैं यदि उनके पास आर्किटेक्चरल क्षमताएं हैं और मेमोरी पते strongly ordered
या device
(ref) के बजाय normal
पर हैं।
इस विशेष मामले में इस तरह के पैरामीटर घोषित करके मानक सी में समान प्रभाव प्राप्त किया जा सकता है : 'int c (अस्थिर int * d, अस्थिर int * e)' –
अर्थ यहां समझाया गया है:
http://en.wikipedia.org/wiki/Memory_ordering
मूल रूप से यह संकेत मिलता है कि विधानसभा कोड निष्पादित किया जाएगा जहां आप इसकी अपेक्षा। यह संकलक को इसके चारों ओर निर्देशों को पुन: व्यवस्थित करने के लिए नहीं कहता है। कोड के इस टुकड़े को पहले निष्पादित किया जाएगा और उसके बाद कोडित किए जाने के बाद कोडित किया जाएगा।
यह अनुक्रम एक कंपाइलर मेमोरी एक्सेस शेड्यूलिंग बाधा है, जैसा कि उडो द्वारा संदर्भित आलेख में उल्लेख किया गया है। यह एक जीसीसी विशिष्ट है - अन्य कंपाइलरों के पास उन्हें वर्णन करने के अन्य तरीके हैं, उनमें से कुछ अधिक स्पष्ट (और कम गूढ़) बयान के साथ हैं।
__asm__
असेंबली भाषा विवरणों को आपके सी कोड में घोंसला दर्ज करने की अनुमति देने का एक जीसीसी विस्तार है - यहां पर साइड इफेक्ट्स निर्दिष्ट करने में सक्षम होने की अपनी संपत्ति के लिए उपयोग किया जाता है जो संकलक को कुछ प्रकार के अनुकूलन करने से रोकता है (जो इस मामले में गलत कोड उत्पन्न करना समाप्त हो सकता है)।
__volatile__
सुनिश्चित करना है कि एएसएम बयान ही किसी अन्य अस्थिर साथ पुनर्क्रमित नहीं है की आवश्यकता होती है किसी भी (सी भाषा में एक गारंटी) तक पहुँचता है।
memory
जीसीसी के लिए एक निर्देश है कि (प्रकार) कहता है कि इनलाइन एएसएम अनुक्रम का वैश्विक स्मृति पर दुष्प्रभाव है, और इसलिए स्थानीय चरों पर केवल प्रभावों को ध्यान में रखना आवश्यक नहीं है।
+1 यह उत्तर प्लस ** उडो ** सही है। यह केवल * कंपाइलर * के लिए एक स्मृति बाधा है। यह एसएमपी हार्डवेयर के लिए काम नहीं करेगा। –
तो आप कैसे निर्णय लेते हैं, एएसएम अस्थिर कथन कहां डालें? – Soundararajan
@ साउंडराराजन: उस प्रश्न का कोई संक्षिप्त जवाब नहीं है। मैं पॉल मैकनेनी के मेमोरी एक्सेस ऑर्डरिंग आवश्यकताओं पर उत्कृष्ट पेपर पढ़ने की सिफारिश करता हूं: http://www.rdrop.com/~paulmck/scalability/paper/whymb.2009.04.05a.pdf और मेमोरी बाधाओं के लिनक्स कर्नेल अवलोकन: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/memory-barriers.txt – unixsmurf
static inline unsigned long arch_local_irq_save(void)
{
unsigned long flags;
asm volatile(
" mrs %0, cpsr @ arch_local_irq_save\n"
" cpsid i" //disabled irq
: "=r" (flags) : : "memory", "cc");
return flags;
}
यदि आप वास्तव में पृष्ठ के शीर्ष पर प्रश्न का उत्तर दे रहे हैं तो कृपया केवल उत्तर पोस्ट करें। यहां सवाल स्पष्टीकरण के लिए पूछता है, आपने ऐसा कुछ भी नहीं दिया है। – Mat
जबकि यह कोड स्निपेट प्रश्न हल कर सकता है, [एक स्पष्टीकरण सहित] (http://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) वास्तव में आपकी पोस्ट की गुणवत्ता में सुधार करने में मदद करता है। याद रखें कि आप भविष्य में पाठकों के लिए प्रश्न का उत्तर दे रहे हैं, और वे लोग आपके कोड सुझाव के कारणों को नहीं जानते हैं। –
- 1. परिवर्तित मदद: __asm__ __volatile__
- 2. यह इनलाइन असेंबली क्यों काम नहीं कर रही है?
- 3. rdtscp, rdtsc के बीच अंतर: स्मृति और cpuid/rdtsc?
- 4. आवंटित स्मृति का दृश्य
- 5. स्मृति
- 6. एएसएम कोड का स्पष्टीकरण
- 7. सी #/एक्सएनए - स्मृति को स्मृति लोड करें - यह कैसे काम करता है?
- 8. स्मृति मुक्त करने का महत्व?
- 9. कक्षाएं अपनी स्मृति का प्रबंधन
- 10. कैसे सीयूडीए निरंतर स्मृति आवंटन काम करता है?
- 11. स्मृति
- 12. स्मृति
- 13. अप्रबंधित स्मृति और प्रबंधित स्मृति
- 14. जीसीसी के साथ इनलाइन असेंबली लिखने के दो तरीके क्यों हैं?
- 15. प्राप्त स्मृति
- 16. अतिरिक्त स्मृति
- 17. स्मृति स्मृति के साथ आर मेमोरी समस्या()
- 18. पायथन डेटा संरचना का स्मृति आकार
- 19. का पता लगा रहा स्मृति रिसाव वस्तुओं
- 20. Git अत्यधिक स्मृति का उपयोग जीसी, असमर्थ
- 21. ptr_vector स्मृति का प्रबंधन कैसे करता है?
- 22. का उपयोग sizeof() malloc'd स्मृति पर
- 23. स्मृति में बाइट का आकार - जावा
- 24. सी भाषा में स्मृति का विभाजन
- 25. CVImageBufferRef से स्मृति का स्वामित्व लें
- 26. स्मृति माप
- 27. स्मृति डंप
- 28. पठन स्मृति
- 29. स्मृति सीमा
- 30. "अशक्त" स्मृति
'एएसएम _volatile_' (http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html#ss5.4) में विस्तार से बताया। लेकिन क्या यह दो अलग-अलग प्रश्न नहीं होना चाहिए? – phoeagon
@phoeagon: यह लाइन, जैसा कि है, एक कंपाइलर मेमोरी एक्सेस शेड्यूलिंग बाधा का एक एकीकृत संचालन है - जबकि दोनों प्रश्न अलग-अलग प्रासंगिक हो सकते हैं, इसलिए पूछे गए प्रश्न का उत्तर देने की संभावना नहीं होगी। – unixsmurf