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


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.