কাস্টম সি ++ বরাদ্দকারীদের উদাহরণ বাধ্য?


176

std::allocatorএকটি কাস্টম সমাধানের পক্ষে খালি করার সত্যিকারের ভাল কারণগুলি কী কী ? আপনি কি এমন কোনও পরিস্থিতি চালিয়ে গিয়েছেন যেখানে নির্ভুলতা, কর্মক্ষমতা, স্কেলিবিলিটি ইত্যাদির জন্য একেবারে প্রয়োজনীয় ছিল? সত্যিই কোন চালাক উদাহরণ?

কাস্টম বরাদ্দকারীরা সর্বদা স্ট্যান্ডার্ড লাইব্রেরির একটি বৈশিষ্ট্য যা আমার খুব বেশি প্রয়োজন হয় নি। আমি কেবল ভাবছিলাম যে এখানে এসও-তে থাকা কেউ যদি তাদের অস্তিত্বের ন্যায্যতা প্রমাণের জন্য কিছু বাধ্যমূলক উদাহরণ সরবরাহ করতে পারে।

উত্তর:


121

আমি এখানে উল্লেখ হিসাবে , আমি ইন্টেল টিবিবি এর কাস্টম এসটিএল বরাদ্দকারীকে কেবল একটি একক পরিবর্তন করে একটি মাল্টিথ্রেডেড অ্যাপ্লিকেশনটির কার্যকারিতা উন্নত করতে দেখেছি

std::vector<T>

প্রতি

std::vector<T,tbb::scalable_allocator<T> >

(এটি টিবিবি'র নিফটি থ্রেড-প্রাইভেট হিপগুলি ব্যবহার করতে বরাদ্দকারীকে স্যুইচ করার একটি দ্রুত এবং সুবিধাজনক উপায়; এই নথিতে পৃষ্ঠা 7 দেখুন )


3
দ্বিতীয় লিঙ্কের জন্য ধন্যবাদ। থ্রেড-প্রাইভেট হিপগুলি প্রয়োগ করতে বরাদ্দকারীদের ব্যবহার চালাক। আমি পছন্দ করি যে এটি কাস্টম বরাদ্দকারীদের এমন একটি দৃশ্যে সুস্পষ্ট সুবিধা রয়েছে যা সংস্থান-সীমাবদ্ধ নয় (এম্বেড বা কনসোল)।
নাফ

7
মূল লিঙ্কটি এখন নষ্ট হয়ে গেছে, তবে সিটিসিরের
আর্টো বেনডিকেন

1
আমাকে জিজ্ঞাসা করতে হবে: আপনি কি এই ধরনের ভেক্টরকে নির্ভরযোগ্যভাবে অন্য থ্রেডে স্থানান্তর করতে পারেন? (আমি অনুমান করছি না)
বিক্রয়

@ সেলিবিটজে: যেহেতু ভেক্টরগুলি টিবিবি টাস্কগুলির মধ্যে থেকে চালিত করা হয়েছিল এবং একাধিক সমান্তরাল অপারেশনগুলিতে পুনরায় ব্যবহার করা হচ্ছে এবং টিবিবি কর্মী থ্রেডগুলি কোন কাজগুলি গ্রহণ করবে তার কোনও গ্যারান্টি নেই, তাই আমি সিদ্ধান্ত নিয়েছি যে এটি ঠিক কাজ করে। যদিও দ্রষ্টব্য যে টিবিবি অন্য থ্রেডে একটি থ্রেডে তৈরি জিনিসপত্র মুক্ত করার সাথে কিছু historicতিহাসিক সমস্যা হয়ে দাঁড়িয়েছে (স্পষ্টতই থ্রেডের ব্যক্তিগত হিপস এবং উত্পাদক-ভোক্তার বরাদ্দ ও অবদানের নমুনা সহকারে একটি ক্লাসিক সমস্যা T টিবিবির দাবি যে এটি বরাদ্দকারী এই বিষয়গুলি এড়িয়ে চলে তবে আমি অন্যথায় দেখেছি । হয়তো নতুন সংস্করণে সংশোধন)।
timday

@ আর্টোবেনডিকেন: আপনার লিঙ্কে ডাউনলোড লিঙ্কটি বৈধ বলে মনে হচ্ছে না।
einpoklum

81

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

ইএএসটিএল - বৈদ্যুতিন আর্টস স্ট্যান্ডার্ড টেম্পলেট লাইব্রেরি


14
ইএএসটিএল লিঙ্কের জন্য +1: "গেম ডেভেলপারদের মধ্যে [এসটিএল এর] সর্বাধিক মৌলিক দুর্বলতা হ'ল স্টাড বরাদ্দকারী নকশা, এবং এই দুর্বলতাই ইএসটিএল তৈরিতে সবচেয়ে বেশি অবদান রাখার কারণ ছিল।"
নাফ

65

আমি একটি এমএমএপি-বরাদ্দকারী নিয়ে কাজ করছি যা ভেক্টরকে মেমরি-ম্যাপযুক্ত ফাইল থেকে মেমরি ব্যবহার করতে দেয়। লক্ষ্যটি হ'ল এমএমএপ দ্বারা সরাসরি ভার্চুয়াল মেমরির মধ্যে থাকা স্টোরেজ ব্যবহারকারী ভেক্টর থাকে। আমাদের সমস্যাটি হ'ল সত্যিকারের বৃহত ফাইলগুলি (> 10 গিগাবাইট) মেমরিতে কোনও অনুলিপি ওভারহেড ছাড়াই উন্নত করা, সুতরাং আমার এই কাস্টম বরাদ্দক প্রয়োজন।

এখনও অবধি আমার কাছে কাস্টম বরাদ্দকারীর কঙ্কাল রয়েছে (যা এসটিডি :: বরাদ্দকারী থেকে উদ্ভূত), আমি মনে করি এটি নিজস্ব বরাদ্দ লেখার পক্ষে একটি ভাল সূচনা পয়েন্ট। কোডটি এই টুকরোটি আপনি যেভাবেই ব্যবহার করতে পারেন তা নির্দ্বিধায়:

#include <memory>
#include <stdio.h>

namespace mmap_allocator_namespace
{
        // See StackOverflow replies to this answer for important commentary about inheriting from std::allocator before replicating this code.
        template <typename T>
        class mmap_allocator: public std::allocator<T>
        {
public:
                typedef size_t size_type;
                typedef T* pointer;
                typedef const T* const_pointer;

                template<typename _Tp1>
                struct rebind
                {
                        typedef mmap_allocator<_Tp1> other;
                };

                pointer allocate(size_type n, const void *hint=0)
                {
                        fprintf(stderr, "Alloc %d bytes.\n", n*sizeof(T));
                        return std::allocator<T>::allocate(n, hint);
                }

                void deallocate(pointer p, size_type n)
                {
                        fprintf(stderr, "Dealloc %d bytes (%p).\n", n*sizeof(T), p);
                        return std::allocator<T>::deallocate(p, n);
                }

                mmap_allocator() throw(): std::allocator<T>() { fprintf(stderr, "Hello allocator!\n"); }
                mmap_allocator(const mmap_allocator &a) throw(): std::allocator<T>(a) { }
                template <class U>                    
                mmap_allocator(const mmap_allocator<U> &a) throw(): std::allocator<T>(a) { }
                ~mmap_allocator() throw() { }
        };
}

এটি ব্যবহার করতে, নিম্নলিখিত হিসাবে একটি এসটিএল ধারক ঘোষণা করুন:

using namespace std;
using namespace mmap_allocator_namespace;

vector<int, mmap_allocator<int> > int_vec(1024, 0, mmap_allocator<int>());

এটি যখনই মেমরি বরাদ্দ করা হয় লগ করতে উদাহরণস্বরূপ ব্যবহার করা যেতে পারে। যা প্রয়োজনীয় তা হ'ল রিবাইন্ড স্ট্রাক্ট, অন্যথায় ভেক্টর ধারক সুপারক্লাস বরাদ্দ / ডিলোকেট পদ্ধতিগুলি ব্যবহার করে।

আপডেট: মেমরি ম্যাপিং বরাদ্দকারী এখন https://github.com/johannesthoma/mmap_allocator এ উপলব্ধ এবং এলজিপিএল। আপনার প্রকল্পের জন্য নির্দ্বিধায় এটি ব্যবহার করুন।


17
মাত্র একটি মাথা আপ, std থেকে প্রাপ্ত :: বরাদ্দকারী আসলে বরাদ্দকারীদের লেখার মূর্তিযুক্ত উপায় নয়। পরিবর্তে আপনার বরাদ্দকারী_প্রেটগুলিকে লক্ষ্য করা উচিত, যা আপনাকে খালি সর্বনিম্ন কার্যকারিতা সরবরাহ করতে দেয় এবং বৈশিষ্ট্য শ্রেণি বাকিটি সরবরাহ করবে। দ্রষ্টব্য যে এসটিএল সর্বদা আপনার বরাদ্দকারীকে সরাসরি বরাদ্দকারী_ট্রাটগুলির মাধ্যমে ব্যবহার করে, সুতরাং আপনাকে নিজের বরাদ্দকারীর_র উল্লেখ করতে হবে না স্টাড :: বরাদ্দকারী থেকে প্রাপ্তির জন্য তেমন উত্সাহ নেই (যদিও এই কোডটি নির্বিশেষে সহায়ক সূচনামূলক বিন্দু হতে পারে)।
নীড় ফ্রিডম্যান

25

আমি একটি মাইএসকিউএল স্টোরেজ ইঞ্জিন নিয়ে কাজ করছি যা এর কোডের জন্য সি ++ ব্যবহার করে। আমরা মেমরির জন্য মাইএসকিউএল এর সাথে প্রতিযোগিতা করার চেয়ে মাইএসকিউএল মেমরি সিস্টেমটি ব্যবহার করতে একটি কাস্টম বরাদ্দকারী ব্যবহার করছি। এটি আমাদের নিশ্চিত করার অনুমতি দেয় যে ব্যবহারকারী মাইএসকিউএল ব্যবহারের জন্য কনফিগার করেছেন, "অতিরিক্ত" নয় হিসাবে আমরা মেমরিটি ব্যবহার করছি।


21

গাদা পরিবর্তে মেমরি পুল ব্যবহার করতে কাস্টম বরাদ্দকারীদের ব্যবহার করা দরকারী। এটি অন্য অনেকের মধ্যে একটি উদাহরণ।

বেশিরভাগ ক্ষেত্রে এটি অবশ্যই একটি অকালীন অপটিমাইজেশন। তবে এটি নির্দিষ্ট প্রসঙ্গে (এম্বেডড ডিভাইস, গেমস ইত্যাদি) খুব কার্যকর হতে পারে।


3
বা, যখন সেই মেমরি পুলটি ভাগ করা হয়।
অ্যান্থনি

9

আমি কাস্টম এসটিএল বরাদ্দকারীর সাথে সি ++ কোডটি লিখিনি, তবে আমি সি ++ তে লিখিত একটি ওয়েবসভার কল্পনা করতে পারি, যা এইচটিটিপি অনুরোধের প্রতিক্রিয়া জানাতে প্রয়োজনীয় অস্থায়ী ডেটা স্বয়ংক্রিয়ভাবে মোছার জন্য একটি কাস্টম বরাদ্দকারী ব্যবহার করে। কাস্টম বরাদ্দকারী একবারে প্রতিক্রিয়া উত্পন্ন হওয়ার সাথে সাথে সমস্ত অস্থায়ী ডেটা মুক্ত করতে পারে।

কাস্টম বরাদ্দকারী (যা আমি ব্যবহার করেছি) এর জন্য অন্য সম্ভাব্য ব্যবহারের ক্ষেত্রে একটি ইউনিট পরীক্ষা লিখে প্রমাণ করা হচ্ছে যে কোনও ফাংশনের আচরণ তার ইনপুটটির কিছু অংশের উপর নির্ভর করে না। কাস্টম বরাদ্দকারী কোনও প্যাটার্ন সহ মেমরি অঞ্চলটি পূরণ করতে পারে।


5
দেখে মনে হচ্ছে প্রথম উদাহরণটি হ'ল ডিস্ট্রাক্টরের কাজ, বরাদ্দকারী নয়।
মাইকেল ডারস্ট

2
আপনি যদি গাদা থেকে মেমরির প্রাথমিক বিষয়বস্তুর উপর নির্ভর করে আপনার প্রোগ্রামটি সম্পর্কে উদ্বিগ্ন হন তবে ভালগ্রাইন্ডে চালানো একটি দ্রুত (অর্থাত রাতারাতি!) আপনাকে একটি উপায় বা অন্য উপায় জানতে দেবে।
সিডিসন 37

3
@ অ্যান্ট্রোপমোরফিক: ডিস্ট্রাক্টর এবং কাস্টম বরাদ্দকারী একসাথে কাজ করবে, ধ্বংসকারী প্রথমে চলবে, তারপরে কাস্টম বরাদ্দকারীকে মুছুন, যা ফ্রি (...) বলবে না, তবে ফ্রি (...) বলা হবে পরে, যখন অনুরোধ পরিবেশন শেষ হয়েছে। এটি ডিফল্ট বরাদ্দকারীর চেয়ে দ্রুত হতে পারে এবং অ্যাড্রেস স্পেস বিভাজন হ্রাস করতে পারে।
পিটিএস

8

জিপিইউ বা অন্যান্য সহ-প্রসেসরগুলির সাথে কাজ করার সময় কখনও কখনও কোনও বিশেষ উপায়ে মূল স্মৃতিতে ডেটা স্ট্রাকচার বরাদ্দ করা উপকারী । মেমরি বরাদ্দের এই বিশেষ উপায়টি একটি সুবিধাজনক ফ্যাশনে কাস্টম বরাদ্দকারীর মধ্যে প্রয়োগ করা যেতে পারে।

এক্সিলারেটরগুলি ব্যবহারের সময় ত্বক চালকের মাধ্যমে কাস্টম বরাদ্দ কেন উপকারী হতে পারে তা নিম্নলিখিত:

  1. কাস্টম বরাদ্দের মাধ্যমে এক্সিলারেটর রানটাইম বা ড্রাইভারকে মেমরি ব্লক সম্পর্কে অবহিত করা হয়
  2. এছাড়াও অপারেটিং সিস্টেমটি নিশ্চিত করতে পারে যে মেমরির বরাদ্দ হওয়া ব্লকটি পৃষ্ঠা-লকড রয়েছে (কেউ কেউ এই পিনড মেমরিটিকে কল করে ), যা অপারেটিং সিস্টেমের ভার্চুয়াল মেমরি সাবসিস্টেমটি মেমরির মধ্যে বা থেকে পৃষ্ঠা সরিয়ে বা সরিয়ে ফেলতে পারে না
  3. যদি ১ এবং ২ হোল্ড করে এবং কোনও পৃষ্ঠা-লক করা মেমরি ব্লক এবং একটি এক্সিলাররের মধ্যে একটি ডেটা স্থানান্তর করার অনুরোধ করা হয়, রানটাইম সরাসরি মেমরির ডেটা অ্যাক্সেস করতে পারে যেহেতু এটি কোথায় তা জানে এবং এটি নিশ্চিত হতে পারে যে অপারেটিং সিস্টেমটি তা করেন নি সরান / এটি সরান
  4. এটি একটি মেমরি অনুলিপি সংরক্ষণ করে যা মেমরির সাথে ঘটে যা একটি পৃষ্ঠা-লকড পদ্ধতিতে বরাদ্দ করা হয়েছিল: তাত্পর্যকারী দিয়ে ডেটা মুখ্য মেমোরিতে একটি পৃষ্ঠা-লক করা মঞ্চে অনুলিপি করতে হবে (ডিএমএর মাধ্যমে) )

1
... পৃষ্ঠা সারিবদ্ধ মেমরি ব্লকগুলি ভুলে যাবেন না। এটি বিশেষত কার্যকর যদি আপনি কোনও ড্রাইভারের সাথে কথা বলছেন (অর্থাত্ ডিএমএর মাধ্যমে এফপিজিএ সহ) এবং আপনার ডিএমএ স্ক্যাটারলিস্টগুলির জন্য পৃষ্ঠা-অফসেটগুলি গণনা করার ঝামেলা এবং ওভারহেড না চান।
জানুয়ারী

7

আমি এখানে কাস্টম বরাদ্দকারী ব্যবহার করছি; আপনি এমনকি বলতে পারেন এটি অন্যান্য কাস্টম গতিশীল মেমরি পরিচালনার চারপাশে কাজ করা ছিল ।

পটভূমি: আমাদের কাছে ম্যালোক, কলোক, ফ্রি এবং অপারেটরের বিভিন্ন রূপ নতুন এবং মুছে ফেলার জন্য ওভারলোড রয়েছে এবং লিঙ্কারটি আনন্দের সাথে এসটিএলকে আমাদের জন্য এটি ব্যবহার করে। এটি আমাদের অটোমেটিক ছোট অবজেক্ট পুলিং, ফাঁস সনাক্তকরণ, বরাদ্দ পূরণ, ফ্রি ফিল, সেন্ড্রিগুলির সাথে প্যাডিং বরাদ্দ, নির্দিষ্ট বরাদ্দের জন্য ক্যাশে-লাইন সারিবদ্ধকরণ এবং বিলম্বিত মুক্তের মতো কাজগুলি করতে দেয়।

সমস্যাটি হচ্ছে, আমরা একটি এম্বেডযুক্ত পরিবেশে চলছি - একটি বর্ধিত সময়কালে সঠিকভাবে ফাঁস সনাক্তকরণ অ্যাকাউন্টিং করার জন্য পর্যাপ্ত মেমরি নেই। কমপক্ষে, স্ট্যান্ডার্ড র‌্যামে নয় - কাস্টম বরাদ্দকরণের ক্রিয়াকলাপের মাধ্যমে অন্য যে কোনও জায়গায় র‌্যামের উপলব্ধ রয়েছে।

সমাধান: একটি কাস্টম বরাদ্দকারী লিখুন যা বর্ধিত হিপ ব্যবহার করে এবং কেবল মেমরি ফাঁস ট্র্যাকিং আর্কিটেকচারের অভ্যন্তরীণ ক্ষেত্রে এটি ব্যবহার করুন ... সমস্ত কিছু স্বাভাবিক নতুন / ডিফল্ট ওভারলোডগুলি ডিফল্ট হয় যা ফাঁস ট্র্যাকিং করে। এটি ট্র্যাকারকে নিজেই ট্র্যাকিং এড়িয়ে চলে (এবং অতিরিক্ত প্যাকিং কার্যকারিতাও কিছুটা সরবরাহ করে, আমরা ট্র্যাকার নোডগুলির আকার জানি)।

আমরা একই কারণে ফাংশন ব্যয় প্রোফাইলিং ডেটা রাখতে এটি ব্যবহার করি; প্রতিটি ফাংশন কল এবং রিটার্নের পাশাপাশি থ্রেড সুইচগুলির জন্য একটি এন্ট্রি লিখলে দ্রুত ব্যয়বহুল হতে পারে। কাস্টম বরাদ্দকারী আবার একটি বৃহত্তর ডিবাগ মেমরি ক্ষেত্রে ছোট বরাদ্দ দেয়।


5

আমি আমার প্রোগ্রামের এক অংশে বরাদ্দ / ডিএলোকেশনগুলির সংখ্যা গণনা করতে এবং এটি কতক্ষণ সময় নেয় তা পরিমাপ করার জন্য একটি কাস্টম বরাদ্দকারী ব্যবহার করছি। এটি অর্জন করার অন্যান্য উপায় রয়েছে তবে এই পদ্ধতিটি আমার পক্ষে খুব সুবিধাজনক। এটি বিশেষত দরকারী যে আমি আমার পাত্রে কেবলমাত্র একটি সাবসেটের জন্য কাস্টম বরাদ্দকারীকে ব্যবহার করতে পারি।


4

একটি অপরিহার্য পরিস্থিতি: কোডটি লেখার সময় অবশ্যই মডিউল (এক্সই / ডিএলএল) সীমানা জুড়ে কাজ করা উচিত, কেবলমাত্র একটি মডিউলে আপনার বরাদ্দ এবং মুছে ফেলা আবশ্যক।

আমি যেখানে এটি ছুটে এসেছি উইন্ডোজের একটি প্লাগইন আর্কিটেকচার। এটি অত্যাবশ্যক যে, উদাহরণস্বরূপ, আপনি যদি ডিএলএল সীমানা জুড়ে স্টাডি :: স্ট্রিংটি পাস করেন তবে স্ট্রিংয়ের যে কোনও পুনঃপ্রেরণটি সেখান থেকে উদ্ভূত হয়েছে, ডিএলএলে হিপ নয় যা আলাদা হতে পারে * occur

* এটি আসলে এর চেয়ে আরও জটিল, আপনি যদি সিআরটির সাথে ডায়নামিকভাবে লিঙ্ক করছেন এটি কোনওভাবেই কাজ করতে পারে। তবে যদি প্রতিটি ডিএলএল সিআরটি-র একটি স্থিতিশীল লিঙ্ক থাকে তবে আপনি ব্যথার জগতে চলে যাচ্ছেন, যেখানে অবিচ্ছিন্ন বরাদ্দ ত্রুটি ক্রমাগত ঘটে থাকে।


আপনি যদি ডিএলএল সীমানা পেরিয়ে অবজেক্টগুলি পাস করেন তবে আপনার উভয় পক্ষের জন্য মাল্টি-থ্রেডেড (ডিবাগ) ডিএলএল (/ এমডি (ডি)) সেটিংটি ব্যবহার করা উচিত। সি ++ মডিউল সমর্থন মাথায় রেখে ডিজাইন করা হয়নি। বিকল্পভাবে আপনি COM ইন্টারফেসের পিছনে সমস্ত কিছু রক্ষা করতে এবং কোটাস্কেমেমোক ব্যবহার করতে পারেন। প্লাগইন ইন্টারফেসগুলি ব্যবহারের এটি সর্বোত্তম উপায় যা কোনও নির্দিষ্ট সংকলক, এসটিএল বা বিক্রেতার কাছে আবদ্ধ নয়।
gast128

পুরানো ছেলেরা এর জন্য নিয়ম করে: এটি করবেন না। ডিএলএল এপিআইতে এসটিএল প্রকারগুলি ব্যবহার করবেন না। এবং ডিএলএল এপিআই সীমানা জুড়ে গতিশীল মেমরি বিনামূল্যে দায়িত্ব পাস করবেন না। কোনও সি ++ এবিআই নেই - সুতরাং আপনি যদি প্রতিটি ডিএলএলকে সিপিআইপি হিসাবে বিবেচনা করেন তবে আপনি সম্ভাব্য সমস্যাগুলির একটি সম্পূর্ণ শ্রেণি এড়ান। অবশ্যই "সি ++ বিউটি" ব্যয়ে। বা অন্যান্য মন্তব্য হিসাবে পরামর্শ দেয়: COM ব্যবহার করুন। কেবল সাদামাটা সি ++ একটি খারাপ ধারণা।
বিটিকলারের

3

আমি যখন এটি ব্যবহার করেছি তার একটি উদাহরণ খুব সংস্থানযুক্ত এম্বেডড সিস্টেমগুলিতে কাজ করছিল। আসুন আপনাকে বলুন যে আপনার কাছে 2k র্যাম ফ্রি রয়েছে এবং আপনার প্রোগ্রামটিতে সেই স্মৃতি থেকে কিছু ব্যবহার করতে হবে। আপনি স্ট্যাকের মধ্যে নেই এমন কোথাও 4-5 সিকোয়েন্সগুলি সংরক্ষণ করতে হবে এবং অতিরিক্ত এই জিনিসগুলি যেখানে সংরক্ষণ করা হয় তার উপর আপনার খুব সুনির্দিষ্ট অ্যাক্সেস থাকা দরকার, এটি এমন একটি পরিস্থিতি যেখানে আপনি নিজের বরাদ্দকারী লিখতে চাইতে পারেন। ডিফল্ট প্রয়োগগুলি মেমরিটিকে খণ্ডিত করতে পারে, আপনার যদি পর্যাপ্ত মেমরি না থাকে এবং আপনার প্রোগ্রামটি পুনরায় আরম্ভ করতে না পারেন তবে এটি গ্রহণযোগ্য নয়।

যে প্রকল্পে আমি কাজ করছিলাম সেটি হ'ল কিছু স্বল্প চালিত চিপগুলিতে AVR-GCC ব্যবহার করা। আমাদের ভেরিয়েবল দৈর্ঘ্যের 8 টি সিকোয়েন্স সংরক্ষণ করতে হয়েছিল তবে একটি সর্বাধিক পরিচিত with মেমরি ব্যবস্থাপনা মান গ্রন্থাগার বাস্তবায়নম্যালোক / ফ্রি চারপাশের একটি পাতলা মোড়ক যা মেমোরির বরাদ্দ মেমরির শেষ অংশটি শেষ করার জন্য একটি পয়েন্টার সহ প্রতিটি বরাদ্দ মেমরির প্রিন্ট করে আইটেমগুলি কোথায় রাখবে তা ট্র্যাক করে। একটি নতুন টুকরো মেমরি বরাদ্দ করার সময় মানক বরাদ্দকারীকে পরবর্তী ব্লকটি পাওয়া যায় যেখানে মেমরির অনুরোধ করা আকারটি মাপসই করা হবে তা পরবর্তী ব্লকটি খুঁজতে মেমরির প্রতিটি টুকরো ধরে যেতে হবে walk একটি ডেস্কটপ প্ল্যাটফর্মে এই কয়েকটি আইটেমের জন্য এটি খুব দ্রুত হবে তবে আপনার মনে রাখতে হবে যে এই কয়েকটি মাইক্রোকন্ট্রোলারের তুলনায় খুব ধীর এবং আদিম। অতিরিক্তভাবে মেমরি খণ্ডিত হওয়া সমস্যাটি একটি বিশাল সমস্যা ছিল যার অর্থ আমাদের কাছে সত্যই ভিন্ন উপায় গ্রহণ করা ছাড়া উপায় ছিল না।

সুতরাং আমরা যা করেছি তা হ'ল আমাদের নিজস্ব মেমরি পুলটি বাস্তবায়ন করা । মেমরির প্রতিটি ব্লক আমাদের এটির যে বৃহত্তম সিকোয়েন্সের প্রয়োজন তা ফিট করার জন্য যথেষ্ট বড় ছিল। এটি সময়ের আগে মেমরির স্থির আকারের ব্লকগুলি বরাদ্দ করে এবং বর্তমানে মেমরির কোন ব্লকগুলি ব্যবহৃত হয় তা চিহ্নিত করে। আমরা এটি একটি 8 বিট পূর্ণসংখ্যার রেখে যেখানে প্রতিটি বিট যদি একটি নির্দিষ্ট ব্লক ব্যবহার করা হয় তবে এটি উপস্থাপন করে did পুরো প্রক্রিয়াটি দ্রুততর করার চেষ্টা করার জন্য আমরা এখানে মেমরির ব্যবহার বন্ধ করে দিয়েছি, যা আমাদের ক্ষেত্রে ন্যায্য ছিল যেহেতু আমরা এই মাইক্রোকন্ট্রোলার চিপটিকে সর্বাধিক প্রসেসিং ক্ষমতার কাছে ঠেলে দিচ্ছিলাম।

এম্বেড থাকা সিস্টেমগুলির প্রসঙ্গে আপনার নিজের কাস্টম বরাদ্দককে লিখতে আমি আরও অনেকবার দেখতে পাচ্ছি, উদাহরণস্বরূপ যদি সিকোয়েন্সের জন্য মেমরিটি মূল র্যাম না হয় তবে এই প্ল্যাটফর্মগুলিতে প্রায়শই ক্ষেত্রে হতে পারে ।


3

বরাদ্দকারীদের নিয়ে আন্দ্রে আলেকজান্দ্রেস্কুর সিপিপিসন 2015 আলাপের বাধ্যতামূলক লিঙ্ক:

https://www.youtube.com/watch?v=LIb3L4vKZ7U

সুন্দর জিনিসটি হ'ল কেবল সেগুলি তৈরি করা আপনাকে কীভাবে সেগুলি ব্যবহার করবে সে সম্পর্কে ধারণাগুলি ভাবতে সহায়তা করে :-)


2

ভাগ করা মেমরির জন্য এটি কেবল পাত্রে মাথা নয়, তবে এতে থাকা ডেটা ভাগ করা মেমরির মধ্যেও সংরক্ষণ করা গুরুত্বপূর্ণ।

এর বরাদ্দকরণ বুস্ট :: Interprocess একটি ভাল উদাহরণ। যাইহোক, আপনি এখানে যেমন পড়তে পারেন সমস্ত এসটিএল কনটেইনারকে ভাগ করে নেওয়া মেমরিটি সামঞ্জস্য করতে (বিভিন্ন প্রক্রিয়াতে বিভিন্ন ম্যাপিং অফসেটের কারণে, পয়েন্টারগুলি "ব্রেক" হতে পারে) যথেষ্ট নয়।


2

কিছু সময় আগে আমি এই সমাধানটি আমার কাছে খুব দরকারী বলে খুঁজে পেয়েছি: এসটিএল পাত্রে দ্রুত সি ++ 11 বরাদ্দকারী । এটি VS2017 (~ 5x) পাশাপাশি জিসিসিতে (x 7x) এসটিএল পাত্রে সামান্য গতি বাড়ায়। এটি মেমরি পুলের উপর ভিত্তি করে একটি বিশেষ উদ্দেশ্যে বরাদ্দকারী। এটি এসটিএল কনটেইনারগুলির সাহায্যে আপনি যে পদ্ধতিটি জিজ্ঞাসা করছেন কেবল তার জন্য ধন্যবাদ ব্যবহার করা যেতে পারে।


1

আমি ব্যক্তিগতভাবে ছোট আইটেমগুলির জন্য মেমরির ব্যবহারের অনুকূলকরণের জন্য লোকি :: বরাদ্দকারী / স্মলঅবজেক্টটি ব্যবহার করি - যদি আপনাকে সত্যিকারের ছোট ছোট বস্তুর (1 থেকে 256 বাইট) মাঝারি পরিমাণে কাজ করতে হয় তবে এটি ভাল দক্ষতা এবং সন্তোষজনক কার্য সম্পাদন দেখায়। এটি স্ট্যান্ডার্ড সি ++ নতুন / মুছে ফেলা বরাদ্দের চেয়ে 30 গুন বেশি দক্ষ হতে পারে যদি আমরা বিভিন্ন আকারের ছোট ছোট অবজেক্টের মাঝারি পরিমাণে বরাদ্দ দেওয়ার কথা বলি। এছাড়াও, "কুইকহ্যাপ" নামে একটি ভিসি-নির্দিষ্ট সমাধান রয়েছে, এটি সর্বোত্তম সম্ভাব্য পারফরম্যান্স নিয়ে আসে (যথাযথভাবে 99 টির মধ্যে ব্লকের বরাদ্দ / জমা হওয়া ব্লকের ঠিকানাটি পড়ুন এবং লিখে ফেলুন) (9)% কেস - সেটিংস এবং প্রারম্ভিককরণের উপর নির্ভর করে), তবে একটি উল্লেখযোগ্য ওভারহেড ব্যয়ে - এটির জন্য ব্যয় প্রতিটি পয়েন্টার এবং প্রতিটি নতুন মেমরি ব্লকের জন্য একটি অতিরিক্ত প্রয়োজন। এটা '

স্ট্যান্ডার্ড সি ++ নতুন / ডিলিট বাস্তবায়ন নিয়ে সমস্যাটি হ'ল এটি সাধারণত সি ম্যালোক / ফ্রি বরাদ্দের জন্য কেবল একটি মোড়ক এবং এটি 1024+ বাইটের মতো মেমরির বৃহত ব্লকগুলির পক্ষে ভাল কাজ করে। পারফরম্যান্সের ক্ষেত্রে এটির একটি উল্লেখযোগ্য ওভারহেড রয়েছে এবং কখনও কখনও ম্যাপিংয়ের জন্য অতিরিক্ত মেমরি ব্যবহৃত হয়। সুতরাং, বেশিরভাগ ক্ষেত্রে কাস্টম বরাদ্দকারীরা কার্যকারিতা সর্বাধিকতর করার জন্য এবং / অথবা ছোট (≤1024 বাইট) বস্তু বরাদ্দকরণের জন্য প্রয়োজনীয় অতিরিক্ত মেমরির পরিমাণ হ্রাস করার পদ্ধতিতে প্রয়োগ করা হয়।


1

গ্রাফিক্স সিমুলেশনে, আমি কাস্টম বরাদ্দকারীগুলির জন্য ব্যবহৃত দেখেছি

  1. প্রান্তিককরণ যে বাধা std::allocator সরাসরি সমর্থন করে না।
  2. স্বল্প-স্থায়ী (কেবলমাত্র এই ফ্রেম) এবং দীর্ঘকালীন বরাদ্দের জন্য পৃথক পুল ব্যবহার করে খণ্ডকে হ্রাস করা।
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.