एसटीडी बनाने के लिए आधुनिक दृष्टिकोण :: वेक्टर संरेखित मेमोरी को आवंटित करता है


11

निम्नलिखित प्रश्न , संबंधित है लेकिन जवाब पुराने हैं, और उपयोगकर्ता से टिप्पणी मार्क Glisse पता चलता है कि इस समस्या यह है कि पर्याप्त रूप से विचार विमर्श नहीं किया जा सकता है के लिए सी के बाद से ++ 17 नए दृष्टिकोण हैं।

मैं SIMD के लिए ठीक से काम कर रही मेमोरी को प्राप्त करने की कोशिश कर रहा हूं, जबकि अभी भी सभी डेटा तक पहुंच है।

इंटेल पर, अगर मैं एक फ्लोट वेक्टर का प्रकार बनाता हूं __m256, और 8 के कारक द्वारा मेरे आकार को कम करता हूं, तो यह मुझे संरेखित मेमोरी देता है।

उदाहरण के लिए std::vector<__m256> mvec_a((N*M)/8);

थोड़े हैक किए गए तरीके से, मैं फ्लोट करने के लिए वेक्टर तत्वों को संकेत दे सकता हूं, जो मुझे व्यक्तिगत फ्लोट मानों तक पहुंचने की अनुमति देता है।

इसके बजाय, मैं ऐसा करना पसंद करूंगा std::vector<float>जो सही ढंग से संरेखित हो, और इस तरह से __m256और अन्य सिमडी प्रकारों को बिना सेगफॉल्टिंग के लोड किया जा सकता है ।

मैं align_alloc में देख रहा हूं

यह मुझे एक सी-शैली सरणी दे सकता है जो सही ढंग से संरेखित है:

auto align_sz = static_cast<std::size_t> (32);
float* marr_a = (float*)aligned_alloc(align_sz, N*M*sizeof(float));

हालांकि मैं अनिश्चित हूं कि यह कैसे किया जाए std::vector<float>। का std::vector<float>स्वामित्व देना marr_a संभव नहीं लगता है

मैंने कुछ सुझाव देखे हैं कि मुझे एक कस्टम एलोकेटर लिखना चाहिए , लेकिन यह बहुत काम की तरह लगता है, और शायद आधुनिक सी ++ के साथ एक बेहतर तरीका है?


1
बिना segfaulting ... या जब आप उपयोग करते हैं तो कैश-लाइन विभाजन से संभावित मंदी के बिना _mm256_loadu_ps(&vec[i])। (हालांकि ध्यान दें कि डिफ़ॉल्ट ट्यूनिंग विकल्पों के साथ जीसीसी विभाजन नहीं-गारंटी गठबंधन 256-बिट लोड / स्टोर vmovups XMM / vinsertf128 में। तो वहाँ है का उपयोग करने का लाभ _mm256_loadअधिक loaduहै, तो आप के बारे में परवाह कैसे जीसीसी पर अपने कोड compiles अगर कोई भूल उपयोग -mtune=...या -march=विकल्प।)
पीटर कॉर्ड्स

जवाबों:


1

वैक्टर सहित मानक C ++ लाइब्रेरी के सभी कंटेनरों में एक वैकल्पिक टेम्प्लेट पैरामीटर होता है जो कंटेनर के एलोकेटर को निर्दिष्ट करता है , और यह वास्तव में आपके स्वयं के कार्यान्वयन के लिए बहुत काम नहीं है:

class my_awesome_allocator {
};

std::vector<float, my_awesome_allocator> awesomely_allocated_vector;

आपको थोड़ा सा कोड लिखना होगा जो आपके आवंटनकर्ता को लागू करता है, लेकिन यह आपके द्वारा पहले से लिखे गए कोड से बहुत अधिक नहीं होगा। यदि आपको पूर्व-सी ++ 17 समर्थन की आवश्यकता नहीं है, तो आपको केवल आवंटित () और डीललोकेट () विधियों को लागू करने की आवश्यकता है , यही है।


उन्हें विशेषज्ञ की भी जरूरत हैallocator_traits
नाथनऑलिवर

1
यह एक उदाहरण के साथ विहित उत्तर के लिए एक अच्छी जगह हो सकती है कि लोग C ++ के कष्टप्रद हुप्स के माध्यम से कूदने के लिए कॉपी / पेस्ट कर सकते हैं। (बोनस अंक अगर स्टैड को जाने देने का एक तरीका है: वेक्टर हमेशा की तरह जगह में फिर से जगह बनाने की कोशिश करता है C ++ हमेशा आवंटित + कॉपी।) यह भी ध्यान दें कि यह vector<float, MAA>टाइप-संगत vector<float>नहीं है (और इसलिए नहीं हो सकता है। कुछ भी जो इस एलोकेटर के बिना संकलित किए गए .push_backएक सादे पर करता है वह std::vector<float>एक नया आवंटन कर सकता है और न्यूनतम-संरेखित मेमोरी में कॉपी कर सकता है। और नए / हटाएं align_alloc / मुक्त के साथ संगत नहीं है)
पीटर कॉर्ड

1
मुझे नहीं लगता कि इस बात की कोई गारंटी है कि आवंटनकर्ता से लौटाया गया सूचक सीधे आधार के std::vectorसरणी के आधार पते के रूप में उपयोग किया जाता है । उदाहरण के लिए, मैं std::vectorआवंटित मेमोरी में सिर्फ एक पॉइंटर का उपयोग करने के कार्यान्वयन की कल्पना कर सकता हूं जो मूल्यों की सीमा से पहले मेमोरी में अंत / क्षमता / एलोकेटर को स्टोर करता है। यह आसानी से आवंटन द्वारा किए गए संरेखण को पन्नी कर सकता है।
डायटमार कुला

1
सिवाय इसके कि std::vectorइसकी गारंटी। यही वह इसका उपयोग करता है। शायद आपको समीक्षा करनी चाहिए कि सी ++ मानक यहां क्या निर्दिष्ट करता है।
सैम वार्शविक

1
> उन्हें भी विशेषज्ञता चाहिए allocator_traits- नहीं, वे नहीं करते। बस जरूरत है एक अनुपूरक आवंटन लागू करने की।
एंड्रे सेमशेव
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.