2015-03-07 9 views
5

कोड का निम्न भाग पर विचार करें:क्लैंग के साथ संकलन करते समय std :: atomic <double> लागू नहीं किया गया है?

#include <atomic> 

int main(void) { 
    std::atomic<double> aDouble; 
    aDouble = 6.0; 
} 

जी ++ यह ठीक है, जबकि बजना संकलित ++ निम्नलिखित उत्पादन:

clang++ -std=c++11 Main.cpp 
/tmp/Main-d4f0fc.o: In function `std::atomic<double>::store(double, std::memory_order)': 
Main.cpp:(.text._ZNSt6atomicIdE5storeEdSt12memory_order[_ZNSt6atomicIdE5storeEdSt12memory_order]+0x31): undefined reference to `__atomic_store_8' 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 

वे एक ही मानक पुस्तकालय के खिलाफ लिंक नहीं है?

+2

अधिकतर क्लैंग libC++ का उपयोग करता है जबकि gcc libstdC++ का उपयोग करता है। –

+1

इसलिए, यदि आप क्लैंग के साथ एक सिस्टम पर संकलित कर रहे हैं जिसमें केवल जीसीसी मानक लाइब्रेरी स्थापित है, तो आपको शायद क्लैंग में '-lstdC++' ध्वज पास करने की आवश्यकता है। – 5gon12eder

+0

हां, 'clang ++ -std = C++ 11 -lstdC++ Main.cpp' वास्तव में प्रोग्राम को संकलित करता है। तो यह 'libcd ++' है, जबकि 'libcdC++' के दौरान सुविधा को कार्यान्वित नहीं किया गया है? – Rovanion

उत्तर

1

यदि clang++ -stdlib=libstdc++ आपकी समस्या का समाधान नहीं करता है, तो इन कार्यों के कार्यान्वयन के लिए -latomic से लिंक करें।

अपने कंपाइलर को 8-बाइट और संकुचित परमाणुओं को इनलाइन करने का प्रयास करें, हालांकि, लाइब्रेरी फ़ंक्शंस में संभावित रूप से बड़े डाउनसाइड्स हैं।

खबरदार कि पुस्तकालय कार्यों एक स्मृति memory_order_seq_cst की तुलना में कमजोर आदेश देने का समर्थन नहीं करते, इसलिए वे हमेशा उपयोग mfence 86 पर , भले ही स्रोत इस्तेमाल किया relaxed

__atomic_store_8 का 32-बिट x86 संस्करण और भी बदतर है: यह एसएसई या x87 8-बाइट स्टोर के बजाय lock cmpxchg8b का उपयोग करता है। यह इसे गलत तरीके से काम करने के बावजूद काम करता है, लेकिन बड़े पैमाने पर प्रदर्शन दंड पर। इसमें दो अनावश्यक lock or [esp], 0 निर्देश भी हैं जो स्टैक से अपने तर्क लोड करने के आसपास अतिरिक्त बाधाओं के रूप में हैं। विडंबना यह है कि (C11 मोड में है, न कि सी ++ 11) के तहत संरेखित करता है atomic_llong एक struct के अंदर (मैं /usr/lib32/libatomic.so.1.2.0 पर आर्क लिनक्स पर gcc7.1.1 से देख रहा हूँ।)

वर्तमान जीसीसी -m32, लेकिन inlines movq xmm भार/स्टोर, तो यह वास्तव में परमाणु नहीं है। (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65146#c4)

वर्तमान बजना -m32 atomic_llong से 8 बाइट संरेखित करता है यहां तक ​​कि अंदर structs (नियमित long long के विपरीत, जो i386 सिस्टम वी ABI केवल 4 बी के लिए संरेखित करता है)। विडंबना यह है कि क्लैंग लाइब्रेरी फ़ंक्शंस को कॉल जेनरेट करता है, जो lock cmpxchg8b का उपयोग करता है, इसलिए यह वास्तव में कैश-लाइन स्प्लिट के साथ परमाणु है। (Why is integer assignment on a naturally aligned variable atomic?)। तो क्लैंग सुरक्षित है भले ही कुछ जीसीसी-संकलित कोड इसे एक पॉइंटर को गलत तरीके से _Atomic long long पर पास कर दें। लेकिन यह संरचना लेआउट के बारे में जीसीसी से असहमत है, इसलिए यह केवल तभी मदद कर सकता है जब यह संरचनात्मक संरचना के बजाय सीधे परमाणु चर के लिए सूचक हो।

+0

एफडब्ल्यूआईडब्ल्यू, -लैटॉमिक ने मदद की (उबंटू 17.04, क्लैंग 5.0.1-एम 32, सभी जीसीसी-मल्टीलिब इत्यादि स्थापित)। –

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