2013-05-07 7 views
7

अगर मैं एक निश्चित संरेखण आवश्यकता के साथ एक सरल प्रकार को परिभाषित करते हुए कहा प्रकार का एक std::vector<t> हर एक तत्व के लिए संरेखण नहीं सम्मान करना चाहिए?std :: वेक्टर सम्मान alignof (value_type) चाहिए?

, निम्न उदाहरण

typedef std::array<double,3> alignas(32) avx_point; 
std::vector<avx_point> x(10); 
assert(!(std::ptrdiff_t(&(x[0]))&31) && // assert that x[0] is 32-byte aligned 
     !(std::ptrdiff_t(&(x[1]))&31)); // assert that x[1] is 32-byte aligned 

मैंने पाया कि संरेखण आवश्यकता (बिना किसी चेतावनी) 3.2 बजना (के साथ या -stdlib=libc++ के बिना) का उल्लंघन चुपचाप है पर विचार करें, जबकि जीसीसी 4.8.0 मुद्दों एक चेतावनी है कि यह ध्यान नहीं देता std::vector करने के लिए टेम्पलेट तर्क पर गुण (इंटेल संकलक भी alignas को समझने के लिए Daft है, लेकिन अगर मैं __declspec(align(32)) बजाय का उपयोग करें, यह बजना तरह बर्ताव करता है)। दोनों कोड बनाते हैं जो जोर देते हैं।

तो, यह सही व्यवहार या बजना (और icpc) की एक बग और जीसीसी के साथ कोई समस्या है?

संपादित एक प्रश्न टिप्पणी में उठाया जवाब देने के लिए: अगर मैं

typedef typename std::aligned_storage<sizeof (avx_point), 
             alignof(avx_point)>::type avx_storage; 

परिभाषित मैं

sizeof (avx_storage) == 32; 
alignof(avx_storage) == 32; 

लेकिन std::vector<avx_storage> अभी भी पहला तत्व संरेखित करने के लिए विफल रहता है मिल (और इसलिए सभी अन्य भी) clang और gcc के लिए (इस बार चेतावनी के बिना)। तो वहाँ जाहिरा तौर पर कार्यान्वयन के साथ दो मुद्दे हैं: पहला, कि std::allocator<type> भी पहले तत्व के लिए किसी भी संरेखण आवश्यकताओं पर ध्यान नहीं देता (अवैध?) और दूसरा, कि कोई गद्दी बाद तत्वों के संरेखण सुनिश्चित करने के लिए लागू किया जाता है।

+0

ब्याज से, यदि आप 'std :: vector >' की तुलना करते हैं तो क्या होता है? – Useless

उत्तर

3

पहले कि std :: संभाजक भी पहले तत्व के लिए किसी भी संरेखण आवश्यकताओं पर ध्यान नहीं देता (अवैध?)

मैं allocators पर एक विशेषज्ञ होने से दूर कर रहा हूँ, लेकिन यह है कि, दुर्भाग्य से मुझे लगता है , यह कानूनी व्यवहार है। अधिक सटीक, एक आवंटक अनुरोधित संरेखण को अनदेखा कर सकता है। दरअसल, [allocator.requirements], 17.6.3.5/6 कहता है:

एक विशिष्ट ओवर-गठबंधन प्रकार से संबद्ध संरेखण एक संभाजक द्वारा समर्थित नहीं है, तो उस प्रकार के लिए संभाजक की इन्स्टेन्शियशन विफल हो सकता है। आवंटक भी अनुरोधित संरेखण चुपचाप अनदेखा कर सकता है।

आप गठबंधन स्मृति देने के लिए अपना स्वयं का आवंटन लिख सकते हैं। मैं अपने काम पर है कि पहले किया है, लेकिन, दुर्भाग्य से, कॉपीराइट कारणों के लिए, मैं कोड :-(सभी मैं कह सकता हूँ खुलासा नहीं कर सकते, स्पष्ट बात है: यह _aligned_malloc और _aligned_free (जो माइक्रोसॉफ्ट एक्सटेंशन कर रहे हैं) के आधार पर किया गया था या। आप गूगल "को संरेखित किया संभाजक" और कुछ ही विकल्प के लिए ऊपर आ जाएगा कर सकते हैं, जिनमें से एक है

https://gist.github.com/donny-dont/1471329

मैं जोर देना है कि मैं इस संरेखित किया संभाजक के लेखक नहीं कर रहा हूँ और मैं इसे उपयोग नहीं किया है।

अद्यतन

संरेखित किया संभाजक ऊपर दृश्य स्टूडियो/Windows के लिए है, लेकिन यह अन्य प्लेटफार्मों पर गठबंधन allocators लागू करने के लिए एक आधार के रूप में इस्तेमाल किया जा सकता है। आप पॉज़िक्स memalign फ़ंक्शन के परिवार या C11 फ़ंक्शन aligned_alloc का उपयोग कर सकते हैं।

this पोस्ट देखें।

+1

आवंटकों को अनदेखा करने की अनुमति देने के लिए केवल 'alignas' और' alignof' कीवर्ड को पेश करने के लिए मानक का तर्क क्या है? बीटीडब्ल्यू, मेरे पास अपना 'aligned_allocator <>' है, जो बहुत अच्छी तरह से काम करता है (और इसमें कोई बेवकूफ कॉपीराइट समस्या नहीं है)। – Walter

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