2016-08-03 12 views
6

मेरा विचार के साथ पर जाने के लिए है कि दोनों सॉफ्टवेयर और हार्डवेयर स्मृति बाधाओं का उपयोग कर मैं एक कोड है कि संकलक अनुकूलन के साथ संकलित किया गया है के अंदर एक विशेष समारोह के लिए बाहर के आदेश अनुकूलन को अक्षम कर सकता है की कोशिश कर रहा बाध्य करने के लिए स्मृति बाधाओं का उपयोग करनामें आदेश निष्पादन

#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

    शब्दावली: ** आउट ऑफ़ ऑर्डर निष्पादन स्मृति रीडरिंग ** से अलग है। यहां तक ​​कि इन-ऑर्डर सीपीयू को पाइपलाइन किया जाता है और स्टोर बफर से लाभ होता है, खासकर एल 1 में याद रखने वाले स्टोरों के लिए। (https://en.wikipedia.org/wiki/MESI_protocol#Memory_Barriers। एक बार जब वे सट्टा होने के बारे में नहीं जानते हैं, तो उन्हें केवल स्मृति-क्रम तर्क द्वारा ट्रैक किया जा सकता है (यदि आवश्यक हो तो स्टोरस्टोर और लोडस्टोर ऑर्डरिंग को लागू करने के लिए) उनके बारे में पाइपलाइन भूल जाने के बाद एल 1 कैश को प्रतिबद्ध करें।) 'MFENCE' पाइपलाइन को क्रमबद्ध नहीं करता है; यह केवल आदेश को क्रमबद्ध करता है कि स्मृति संचालन विश्व स्तर पर दिखाई देता है। –

    उत्तर

    4

    स्मृति बाधाओं संकलक/सीपीयू कि शिक्षा बताओ बाधा में फिर से नहीं किया जाना चाहिए, उनका मतलब यह नहीं है कि लिखते हैं कि व्यर्थ साबित किया जा सकता है वैसे भी किया जाना चाहिए।

    यदि आप अपने x रूप volatile परिभाषित करते हैं, संकलक धारणा नहीं बना सकते, कि यह केवल इकाई है कि x के बारे में मूल्य परवाह करता है और सी सार मशीन है, जो स्मृति लिखने के लिए है के नियमों का पालन करना पड़ता है है वास्तव में होने के लिए।

    अपने विशिष्ट मामले में आप बाधाओं को छोड़ सकते हैं, क्योंकि यह पहले से ही गारंटी है कि अस्थिर पहुंच एक-दूसरे के खिलाफ पुन: व्यवस्थित नहीं होती हैं।

    यदि आपके पास सी 11 समर्थन है, तो आप _Atomic एस का उपयोग करने से बेहतर हैं, जो अतिरिक्त रूप से गारंटी दे सकता है कि सामान्य असाइनमेंट आपके x के खिलाफ पुन: व्यवस्थित नहीं होंगे और यह एक्सेस परमाणु हैं।


    संपादित करें: जीसीसी (और साथ ही बजना) इस संबंध में असंगत होने लगते हैं और हमेशा इस optimizaton नहीं करेंगे। I opened a GCC bug report regarding this.

    +3

    आपने मुझसे बेहतर जवाब लिखा है। – 2501

    +0

    सही उत्तर। मैंने इसे अब 'अस्थिर' के साथ परीक्षण किया है, और मेमोरी बाधा वाला कोड ठीक उसी तरह संकलित किया गया था जैसा कि मैंने अपेक्षित था (जबकि स्मृति बाधा के बिना कोड अभी भी थोड़ा अनुकूलित किया गया था)। दुर्भाग्य से मैं 'परमाणु' का परीक्षण नहीं कर सकता क्योंकि मेरे पास सी 11 समर्थन नहीं है। – user2162550

    +0

    @ 2501 धन्यवाद। अगर आपको लगता है कि कुछ सुधार किया जा सकता है, तो इसे विस्तारित करने के लिए स्वतंत्र महसूस करें। :) – a3f

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