2013-09-02 6 views
7

यह ज्ञात है कि आपरेशन load() और store() स्मृति बाधाओं memory_order_consume, memory_order_acquire, memory_order_release, memory_order_acq_rel कैश और पाइप लाइन के लिए एक प्रोसेसर निर्देश की आवश्यकता नहीं है के लिए , और कोडांतरक के कोड पर हमेशा std::memory_order_relaxed से मेल खाती है, और इन प्रतिबंधों केवल के अनुकूलन के लिए आवश्यक हैं संकलक: http://www.stdthread.co.uk/forum/index.php?topic=72.0क्या `std :: memory_order_acquire` के अर्थशास्त्र को x86/x86_64 पर प्रोसेसर निर्देशों की आवश्यकता है?

और यह कोड Disassembly कोड store() (MSVS2012 x86_64) के लिए इस बात की पुष्टि करता:

std::atomic<int> a; 
    a.store(0, std::memory_order_relaxed); 
000000013F931A0D mov   dword ptr [a],0 
    a.store(1, std::memory_order_release); 
000000013F931A15 mov   dword ptr [a],1 

लेकिन इस कोड load() (MSVS2012 x86_64) के लिए इस comfirm नहीं करता है, का उपयोग कर lock cmpxchg:

int val = a.load(std::memory_order_acquire); 
000000013F931A1D prefetchw [a] 
000000013F931A22 mov   eax,dword ptr [a] 
000000013F931A26 mov   edx,eax 
000000013F931A28 lock cmpxchg dword ptr [a],edx 
000000013F931A2E jne   main+36h (013F931A26h) 

    std::cout << val << "\n"; 

लेकिन Anthony Williams said:

some_atomic.load (std :: memory_order_acquire) बस करता है से एक साधारण लोड निर्देश, और some_atomic.store (std :: memory_order_release) एक साधारणतक गिर जाता हैस्टोर निर्देश।

कहाँ मैं गलत हूँ, और कहा के रूप में एंथनी विलियम्स std::memory_order_acquire के शब्दों x86/x86_64 lock cmpxchg पर प्रोसेसर निर्देश या केवल एक साधारण लोड अनुदेश mov की आवश्यकता है?

उत्तर: यह इस बग रिपोर्ट के समान ही है: http://connect.microsoft.com/VisualStudio/feedback/details/770885

+1

मुझे यकीन नहीं है कि कंपाइलर जेनरेट करता है, यह आवश्यक है कि किसी विशेष कार्यक्षमता की आवश्यकताओं को निर्धारित करने के लिए एक अच्छा तरीका है - यह अनदेखा नहीं है कि उन कंपाइलर्स "उन्हें जितना अधिक चाहिए" करता है। –

+0

@ मैट पीटर्ससन हाँ, लेकिन कुछ भी करने से कहीं ज्यादा आसान नहीं है। और यह संकलक से आवश्यक था, 'mov' के अलावा कुछ भी नहीं। वास्तव में माइक्रोसॉफ्ट के डेवलपर्स इस सबसे सरल कार्य में विफल रहे हैं: "कुछ भी नहीं"? :) – Alex

+0

मुझे पता है कि एमएस वीसी (कम से कम SOME संस्करण) 'अस्थिर' के रूप में घोषित चर पर अतिरिक्त "लॉकिंग" उत्पन्न करेगा - क्योंकि सी ++ मानक की आवश्यकता नहीं है, लेकिन क्योंकि कोड के कुछ बिट्स जो एकल कोर प्रोसेसर पर काम करने के लिए उपयोग किए जाते हैं यदि आप एसएमपी सिस्टम का उपयोग करते हैं तो खराब काम करें। यह उन स्थितियों में से एक जैसा दिखता है। –

उत्तर

6

सं std::memory_order_acquire के शब्दों x86/x86_64 पर प्रोसेसर निर्देश की आवश्यकता है नहीं करता है।

किसी भी लोड()/x86_64 पर दुकान() संचालन प्रोसेसर निर्देश की आवश्यकता नहीं है (लॉक/बाड़) सटीक atomic.store(val, std::memory_order_seq_cst); जो (LOCK) XCHG या वैकल्पिक आवश्यकता है: MOV (into memory),MFENCE

(कैस को छोड़कर) x86 के लिए

प्रोसेसर स्मृति-बाधाओं-निर्देश, और भी हाथ और PowerPC: http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html

Disassembler जीसीसी 4.8.1 x86_64 - GDB - लोड():

20  temp = a.load(std::memory_order_relaxed); 
    21  temp = a.load(std::memory_order_acquire); 
    22  temp = a.load(std::memory_order_seq_cst); 
0x46140b <+0x007b>   mov 0x38(%rsp),%ebx 
0x46140f <+0x007f>   mov 0x34(%rsp),%esi 
0x461413 <+0x0083>   mov 0x30(%rsp),%edx 

Disassembler जीसीसी 4.8।1 x86_64 - GDB - दुकान(): http://connect.microsoft.com/VisualStudio/feedback/details/770885:

a.store(temp, std::memory_order_relaxed); 
a.store(temp, std::memory_order_release); 
a.store(temp, std::memory_order_seq_cst); 
0x4613dc <+0x004c>   mov %eax,0x20(%rsp) 
0x4613e0 <+0x0050>   mov 0x38(%rsp),%eax 
0x4613e4 <+0x0054>   mov %eax,0x20(%rsp) 
0x4613e8 <+0x0058>   mov 0x38(%rsp),%eax 
0x4613ec <+0x005c>   mov %eax,0x20(%rsp) 
0x4613f0 <+0x0060>   mfence 
0x4613f3 <+0x0063>   mov %ebx,0x20(%rsp) 

Disassembler MSVS 2012 x86_64 - - लोड() यह इस बग रिपोर्ट रूप में ही है

temp = a.load(std::memory_order_relaxed); 
000000013FE51A1F prefetchw [a] 
000000013FE51A24 mov   eax,dword ptr [a] 
000000013FE51A28 nop   dword ptr [rax+rax] 
000000013FE51A30 mov   ecx,eax 
000000013FE51A32 lock cmpxchg dword ptr [a],ecx 
000000013FE51A38 jne   main+40h (013FE51A30h) 
000000013FE51A3A mov   dword ptr [temp],eax 
    temp = a.load(std::memory_order_acquire); 
000000013FE51A3E prefetchw [a] 
000000013FE51A43 mov   eax,dword ptr [a] 
000000013FE51A47 nop   word ptr [rax+rax] 
000000013FE51A50 mov   ecx,eax 
000000013FE51A52 lock cmpxchg dword ptr [a],ecx 
000000013FE51A58 jne   main+60h (013FE51A50h) 
000000013FE51A5A mov   dword ptr [temp],eax 
    temp = a.load(std::memory_order_seq_cst); 
000000013FE51A5E prefetchw [a] 
    temp = a.load(std::memory_order_seq_cst); 
000000013FE51A63 mov   eax,dword ptr [a] 
000000013FE51A67 nop   word ptr [rax+rax] 
000000013FE51A70 mov   ecx,eax 
000000013FE51A72 lock cmpxchg dword ptr [a],ecx 
000000013FE51A78 jne   main+80h (013FE51A70h) 
000000013FE51A7A mov   dword ptr [temp],eax 

Disassembler एमएसवीएस 2012 x86_64 - स्टोर():

a.store(temp, std::memory_order_relaxed); 
000000013F8C1A58 mov   eax,dword ptr [temp] 
000000013F8C1A5C mov   dword ptr [a],eax 

    a.store(temp, std::memory_order_release); 
000000013F8C1A60 mov   eax,dword ptr [temp] 
000000013F8C1A64 mov   dword ptr [a],eax 

    a.store(temp, std::memory_order_seq_cst); 
000000013F8C1A68 mov   eax,dword ptr [temp] 
000000013F8C1A6C xchg  eax,dword ptr [a] 
संबंधित मुद्दे

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