मेरा विचार के साथ पर जाने के लिए है कि दोनों सॉफ्टवेयर और हार्डवेयर स्मृति बाधाओं का उपयोग कर मैं एक कोड है कि संकलक अनुकूलन के साथ संकलित किया गया है के अंदर एक विशेष समारोह के लिए बाहर के आदेश अनुकूलन को अक्षम कर सकता है की कोशिश कर रहा बाध्य करने के लिए स्मृति बाधाओं का उपयोग करनामें आदेश निष्पादन
#include <stdio.h>
int main(int argc, char ** argv)
{
int x=0;
asm volatile("": : :"memory");
__sync_synchronize();
x=1;
asm volatile("": : :"memory");
__sync_synchronize();
x=2;
asm volatile("": : :"memory");
__sync_synchronize();
x=3;
printf("%d",x);
return 0;
}
: है, और इसलिए मैं Peterson
या Deker
तरह एल्गोरिदम कि कोई बाहर के आदेश निष्पादन की आवश्यकता का उपयोग कर सॉफ्टवेयर सेमाफोर को लागू कर सकता है, मैं निम्नलिखित कोड है कि दोनों दप बाधा asm volatile("": : :"memory")
और जीसीसी builtin HW बाधा __sync_synchronize
शामिल परीक्षण किया है लेकिन संकलन आउटपुट फ़ाइल है:
main:
.LFB24:
.cfi_startproc
subq $8, %rsp
.cfi_def_cfa_offset 16
mfence
mfence
movl $3, %edx
movl $.LC0, %esi
movl $1, %edi
xorl %eax, %eax
mfence
call __printf_chk
xorl %eax, %eax
addq $8, %rsp
और अगर मैं बाधाओं को हटा कर फिर संकलन, मैं मिलता है:
main
.LFB24:
.cfi_startproc
subq $8, %rsp
.cfi_def_cfa_offset 16
movl $3, %edx
movl $.LC0, %esi
movl $1, %edi
xorl %eax, %eax
call __printf_chk
xorl %eax, %eax
addq $8, %rsp
दोनों Ubuntu 14.04.1 LTS, 86 में gcc -Wall -O2
साथ संकलित।
अपेक्षित परिणाम यह था कि मेमोरी बाधाओं वाले कोड की आउटपुट फ़ाइल में मेरे स्रोत कोड में मेरे मानों के सभी असाइनमेंट होंगे, जिसमें mfence
उनके बीच होगा।
एक संबंधित StackOverflow पोस्ट के अनुसार -
gcc memory barrier __sync_synchronize vs asm volatile("": : :"memory")
जब प्रत्येक यात्रा पर अपने इनलाइन विधानसभा जोड़ने, जीसीसी बाधा अतीत के संचालन के क्रम बदलने के लिए अनुमति नहीं है
और बाद में:
हाउ ver, जब सीपीयू performes इस कोड, यह "हुड के नीचे" संचालन को पुन: व्यवस्थित करने के लिए, जब तक कि यह स्मृति आदेश मॉडल को नहीं तोड़ता है के रूप में अनुमति दी है। इसका मतलब है कि ऑपरेशनों को आदेश से बाहर किया जा सकता है (सीपीयू कि समर्थन करता है तो, सबसे इन दिनों करते हैं)। एक एचडब्ल्यू बाड़ ने इसे रोक दिया होगा।
लेकिन जैसा कि आप देख सकते हैं, स्मृति बाधाओं के साथ कोड और उनके बिना कोड के बीच फर्क सिर्फ इतना है पूर्व एक एक तरह से मैं इसे देखना उम्मीद नहीं थी में mfence
शामिल है, और नहीं सभी कार्य करता है सम्मलित हैं।
क्यों mfence
आदेश क्यों बदल दिया गया है करता है स्मृति बाधाओं के साथ फ़ाइल के आउटपुट फ़ाइल के रूप में मैं expected- नहीं किया गया था? कंपाइलर ने कुछ असाइनमेंट क्यों हटा दिए? क्या संकलक को ऐसे अनुकूलन करने की इजाजत है, भले ही स्मृति बाधा लागू हो और कोड की प्रत्येक पंक्ति को अलग कर दें?स्मृति बाधा प्रकार और उपयोग करने के लिए
संदर्भ: - http://bruceblinn.com/linuxinfo/MemoryBarriers.html
जीसीसी Builtins -
शब्दावली: ** आउट ऑफ़ ऑर्डर निष्पादन स्मृति रीडरिंग ** से अलग है। यहां तक कि इन-ऑर्डर सीपीयू को पाइपलाइन किया जाता है और स्टोर बफर से लाभ होता है, खासकर एल 1 में याद रखने वाले स्टोरों के लिए। (https://en.wikipedia.org/wiki/MESI_protocol#Memory_Barriers। एक बार जब वे सट्टा होने के बारे में नहीं जानते हैं, तो उन्हें केवल स्मृति-क्रम तर्क द्वारा ट्रैक किया जा सकता है (यदि आवश्यक हो तो स्टोरस्टोर और लोडस्टोर ऑर्डरिंग को लागू करने के लिए) उनके बारे में पाइपलाइन भूल जाने के बाद एल 1 कैश को प्रतिबद्ध करें।) 'MFENCE' पाइपलाइन को क्रमबद्ध नहीं करता है; यह केवल आदेश को क्रमबद्ध करता है कि स्मृति संचालन विश्व स्तर पर दिखाई देता है। –