স্ট্যান্ড :: ভেক্টর সারিবদ্ধ মেমরি বরাদ্দ করার আধুনিক পদ্ধতি


11

নিচের প্রশ্নগুলোর , সম্পর্কিত তবে উত্তর বৃদ্ধ হয়েছেন, আর ব্যবহারকারীর কাছ থেকে মন্তব্য মার্ক Glisse প্রস্তাব দেওয়া এই সমস্যার যে পর্যাপ্তরূপে আলোচনা না করা যেতে পারে সি যেহেতু ++, 17 নতুন পন্থা আছে।

আমি সিমডির জন্য সঠিকভাবে কাজ করা সারিবদ্ধ করার চেষ্টা করছি, তখনও সমস্ত ডেটাতে অ্যাক্সেস রয়েছে।

ইন্টেল-এ, আমি যদি টাইপের একটি ভাসমান ভেক্টর তৈরি করি __m256এবং 8 এর ফ্যাক্টর দ্বারা আমার আকার হ্রাস করি তবে এটি আমাকে সারিবদ্ধ মেমরি দেয়।

যেমন std::vector<__m256> mvec_a((N*M)/8);

কিছুটা হ্যাকি পদ্ধতিতে, আমি ভেক্টর উপাদানগুলিতে ভাসমানের জন্য পয়েন্টারগুলি কাস্ট করতে পারি, যা আমাকে স্বতন্ত্র ভাসমানের মানগুলিতে অ্যাক্সেস করতে দেয়।

পরিবর্তে, আমি একটি পছন্দ করতে চাই std::vector<float>যা সঠিকভাবে প্রান্তিক করা আছে, এবং এভাবে __m256সেগফোল্টিং ছাড়াই এবং অন্যান্য সিমডি টাইপগুলিতে লোড করা যায় ।

আমি সারিবদ্ধ_লোক অনুসন্ধান করছি ।

এটি আমাকে সি-স্টাইলের অ্যারে দিতে পারে যা সঠিকভাবে প্রান্তিকিত:

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
সেগফোল্টিং ছাড়াই ... বা আপনি যখন ব্যবহার করবেন তখন ক্যাশে-লাইনটি বিভাজন থেকে সম্ভাব্য ধীরগতি ছাড়াই _mm256_loadu_ps(&vec[i])। (যদিও নোট ডিফল্ট টিউনিং বিকল্প সহ জিসিসি splits না নিশ্চিত-প্রান্তিককৃত 256-বিট লোড / দোকান vmovups XMM / vinsertf128 মধ্যে। তাই সেখানে হয় ব্যবহার করে একটি সুবিধা _mm256_loadওভার loaduআপনি যত্নশীল কিভাবে জিসিসি উপর আপনার কোড প্রনয়ন যদি কেউ ভুলে যায় ব্যবহার -mtune=...বা -march=বিকল্পগুলি))
— পিটার কর্ডেস

উত্তর:


1

ভেক্টর সহ স্ট্যান্ডার্ড সি ++ লাইব্রেরির সমস্ত পাত্রে একটি alচ্ছিক টেম্পলেট প্যারামিটার রয়েছে যা ধারকটির বরাদ্দকারীকে নির্দিষ্ট করে এবং এটি আপনার নিজের বাস্তবায়নের জন্য খুব বেশি কাজ নয়:

class my_awesome_allocator {
};

std::vector<float, my_awesome_allocator> awesomely_allocated_vector;

আপনাকে কিছুটা কোড লিখতে হবে যা আপনার বরাদ্দকারীকে কার্যকর করে, তবে আপনি ইতিমধ্যে লিখেছেন এর চেয়ে বেশি কোড হবে না। আপনার যদি প্রাক-সি ++ 17 সমর্থন প্রয়োজন না হয় আপনার কেবলমাত্র বরাদ্দ () এবং ডিএলোকট () পদ্ধতিগুলি প্রয়োগ করতে হবে, এটি।


তাদেরও বিশেষজ্ঞ করতে হবেallocator_traits
— নাথান অলিভার

1
এটি প্রচলিত উত্তরের জন্য একটি উত্তম উদাহরণ হতে পারে যে লোকেরা সি ++ এর বিরক্তিকর হুপগুলিতে ঝাঁপিয়ে পড়তে কপি / পেস্ট করতে পারে। (বোনাস পয়েন্ট যদি কোনও উপায় থাকে তবে স্ট্যান্ড :: ভেক্টর সাধারণ ব্রেনিডেড সি ++ এর পরিবর্তে স্থানে পুনরায় পুনরায় চেষ্টা করার চেষ্টা করবে + সর্বদা + কপি বরাদ্দ করে)) অবশ্যই নোট করুন যে এটি vector<float, MAA>টাইপ-সামঞ্জস্যপূর্ণ vector<float>নয় (এবং কারণ হতে পারে না) কিছু না .push_backএকটি প্লেইন উপর std::vector<float>এই বরাদ্দকরণ ছাড়া কম্পাইল একটি নতুন বরাদ্দ করতে পারে এবং কপি ন্যূনতমরূপে-প্রান্তিককৃত মেমরিতে নতুন / মুছুন / বিনামূল্যে aligned_alloc সঙ্গে সামঞ্জস্যপূর্ণ) নয়।
— পিটার Cordes

1
আমি মনে করি না যে বরাদ্দকারীর কাছ থেকে ফিরে পয়েন্টারটি সরাসরি std::vectorঅ্যারের ভিত্তি ঠিকানা হিসাবে ব্যবহৃত হবে এমন কোনও গ্যারান্টি নেই । উদাহরণস্বরূপ, আমি std::vectorবরাদ্দ মেমরির মধ্যে কেবলমাত্র একটি পয়েন্টার ব্যবহারের প্রয়োগের কল্পনা করতে পারি যা মানগুলির সীমার পূর্বে স্মৃতিতে শেষ / ক্ষমতা / বরাদ্দক সংরক্ষণ করে। এটি সহজেই বরাদ্দকারী দ্বারা সম্পন্ন প্রান্তিককরণটি বানচাল করতে পারে।
— ডায়েটমার কাহল

1
std::vectorগ্যারান্টি ছাড়া এটি। এটি এটি এর জন্য ব্যবহার করে। সম্ভবত আপনার এখানে সি ++ স্ট্যান্ডার্ড কী নির্দিষ্ট করে তা পর্যালোচনা করা উচিত।
— স্যাম বর্ষাভিক

1
> তাদেরও বিশেষজ্ঞ করতে হবে allocator_traits- না, তারা না। যা প্রয়োজন তা হ'ল একটি অনুগামী বরাদ্দকারীকে বাস্তবায়ন করা।
— আন্দ্রে সেমাসেভ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.