জাল এবং ইমেজ প্রসেসিং, পদার্থবিজ্ঞান ইঞ্জিন এবং রাইট্র্যাকিংয়ের মতো পারফরম্যান্স-সমালোচনামূলক ক্ষেত্রে কাজ করা লিঙ্কযুক্ত তালিকার জন্য আমি সবচেয়ে দরকারী ক্ষেত্রে খুঁজে পেয়েছি হ'ল লিঙ্কযুক্ত তালিকাগুলি আসলে রেফারেন্সের স্থানীয়ত্ব উন্নত করে এবং গাদা বরাদ্দ হ্রাস করে এবং কখনও কখনও এমনকি তুলনায় মেমরির ব্যবহার হ্রাস করে সোজা বিকল্প।
এখন এটি একটি সম্পূর্ণ অক্সিমেরনের মতো মনে হতে পারে যা লিঙ্কযুক্ত তালিকাগুলি প্রায়শই বিপরীত কাজ করার জন্য কুখ্যাত হয়ে থাকে, তবে তাদের একটি অনন্য সম্পত্তি রয়েছে যে প্রতিটি তালিকার নোডের একটি নির্দিষ্ট আকার এবং প্রান্তিককরণের প্রয়োজনীয়তা রয়েছে যা আমরা অনুমতি দেওয়ার জন্য ব্যবহার করতে পারি এগুলিকে নিয়মিতভাবে সংরক্ষণ করা যায় এবং ধ্রুবক-আকারের জিনিসগুলি যেভাবে পরিবর্তনশীল-আকারের জিনিসগুলি পারে না তা স্থির সময়ে সরানো হয়।
ফলস্বরূপ, আসুন একটি কেস নেওয়া যাক যেখানে আমরা চলক-দৈর্ঘ্যের ক্রমটি সংরক্ষণের উপমা সমতুল্য করতে চাই যেখানে মিলিয়ন নেস্টেড ভেরিয়েবল-দৈর্ঘ্যের সাব-সিকোয়েন্স রয়েছে। একটি কংক্রিটের উদাহরণ হ'ল এক মিলিয়ন বহুভুজ (কিছু ত্রিভুজ, কিছু কোয়াড, কিছু পেন্টাগন, কিছু হেক্সাগন, ইত্যাদি) সংরক্ষণ করা একটি সূচকযুক্ত জাল এবং কখনও কখনও বহুভুজগুলি জালের যে কোনও জায়গা থেকে সরানো হয় এবং কখনও কখনও বহুভুজগুলি একটি বিদ্যমান বহুভুজের মধ্যে একটি শীর্ষবিন্দু প্রবেশ করার জন্য পুনরায় তৈরি করা হয় বা একটি অপসারণ। সেক্ষেত্রে আমরা যদি এক মিলিয়ন ক্ষুদ্র সঞ্চয় করে থাকি std::vectors
তবে আমরা প্রতিটি ভেক্টরের পাশাপাশি সম্ভাব্য বিস্ফোরক মেমরির ব্যবহারের জন্য একটি গাদা বরাদ্দের মুখোমুখি হয়ে যাই। এক মিলিয়ন ক্ষুদ্র SmallVectors
এই সমস্যাটি সাধারণ ক্ষেত্রে খুব বেশি ভুগতে পারে না, তবে তারপরে তাদের পূর্বনির্ধারিত বাফার যা পৃথকভাবে গাদা-বরাদ্দ নয় তা এখনও বিস্ফোরক স্মৃতি ব্যবহারের কারণ হতে পারে।
এখানে সমস্যাটি হ'ল এক মিলিয়ন std::vector
দৃষ্টান্তগুলি মিলিয়ন পরিবর্তনশীল দৈর্ঘ্যের জিনিসগুলি সংরক্ষণ করার চেষ্টা করবে। পরিবর্তনশীল-দৈর্ঘ্যের জিনিসগুলি হিপ বরাদ্দ চায় যেহেতু এগুলি খুব কার্যকরভাবে নিখুঁতভাবে সংরক্ষণ করা যায় না এবং ধ্রুবক সময়ে (কমপক্ষে একটি খুব জটিল বরাদ্দকারী ছাড়াই সোজা পদ্ধতিতে) অপসারণ করা যায় না যদি তারা তাদের বিষয়বস্তু স্তূপে অন্য কোথাও না সঞ্চয় করে।
পরিবর্তে, যদি আমরা এটি করি:
struct FaceVertex
{
// Points to next vertex in polygon or -1
// if we're at the end of the polygon.
int next;
...
};
struct Polygon
{
// Points to first vertex in polygon.
int first_vertex;
...
};
struct Mesh
{
// Stores all the face vertices for all polygons.
std::vector<FaceVertex> fvs;
// Stores all the polygons.
std::vector<Polygon> polys;
};
... তারপরে আমরা নাটকীয়ভাবে হ্যাপ বরাদ্দ এবং ক্যাশে মিসের সংখ্যা হ্রাস করেছি। আমরা অ্যাক্সেসের প্রতিটি একক বহুভুতের জন্য গাদা বরাদ্দ এবং সম্ভাব্য বাধ্যতামূলক ক্যাশে মিস করার প্রয়োজনের পরিবর্তে, কেবলমাত্র পুরো জালের মধ্যে থাকা দুটি ভেক্টরগুলির মধ্যে একটির যখন তাদের ক্ষমতা (এক স্বীকৃত ব্যয়) ছাড়িয়েছে তখন কেবলমাত্র গাদা বরাদ্দ প্রয়োজন। এবং যখন একটি প্রান্ত থেকে অন্য প্রান্তে পৌঁছানোর পথটি এখনও তার ভাগটিকে ক্যাশে মিস করতে পারে তবে নোডগুলি স্বতঃস্ফূর্তভাবে সংরক্ষণ করা হয় এবং প্রতিবেশী ভার্টেক্সের সম্ভাবনা থাকতে পারে বলে প্রতি একক বহুভুজ একটি পৃথক গতিশীল অ্যারে সংরক্ষণ করে তবে তার চেয়ে কম হয় often উচ্ছেদের পূর্বে অ্যাক্সেস করা উচিত (বিশেষত বিবেচনা করে যে বহু বহুভুজগুলি তাদের শিখরগুলি একবারে যুক্ত করবে যা বহুভুংশের শীর্ষে সিংহের ভাগকে পুরোপুরি সংলগ্ন করে তোলে)।
এখানে আরও একটি উদাহরণ:
... যেখানে গ্রিড সেলগুলি কণা-কণা সংঘর্ষকে ত্বরান্বিত করার জন্য ব্যবহৃত হয়, বলুন, প্রতি একক ফ্রেমে সরিয়ে 16 মিলিয়ন কণা। সেই কণা গ্রিডের উদাহরণে, লিঙ্কযুক্ত তালিকাগুলি ব্যবহার করে আমরা একটি কণা কেবল একটি গ্রিড সেল থেকে অন্য গ্রহে সরাতে পারি কেবল 3 টি সূচক পরিবর্তন করে। কোনও ভেক্টর থেকে মুছে ফেলা এবং অন্যটিতে ফিরে যাওয়া যথেষ্ট ব্যয়বহুল হতে পারে এবং আরও গাদা বরাদ্দ প্রবর্তন করতে পারে। লিঙ্কযুক্ত তালিকাগুলি একটি ঘরের স্মৃতিও 32-বিটকে হ্রাস করে। বাস্তবায়নের উপর নির্ভর করে একটি ভেক্টর তার গতিশীল অ্যারেটিকে এমনভাবে বিন্যাস করতে পারে যেখানে এটি খালি ভেক্টরের জন্য 32 বাইট নিতে পারে। আমাদের যদি প্রায় এক মিলিয়ন গ্রিড সেল থাকে তবে এটি বেশ পার্থক্য।
... এবং এখানেই আমি লিঙ্কযুক্ত তালিকাগুলি আজকাল সবচেয়ে দরকারী খুঁজে পেয়েছি এবং আমি বিশেষত "ইনডেক্সড লিঙ্কড লিস্ট" প্রকারটি খুঁজে পাই যেহেতু 32-বিট সূচকগুলি 64-বিট মেশিনে লিঙ্কগুলির মেমরির প্রয়োজনীয়তাগুলি অর্ধেক করে দেয় এবং তারা বোঝায় যে নোডগুলি একটি অ্যারেতে স্বচ্ছলভাবে সংরক্ষণ করা হয়।
প্রায়শই আমি স্থির-সময় অপসারণ এবং সন্নিবেশকে কোথাও মঞ্জুরি দেওয়ার জন্য সূচিযুক্ত ফ্রি তালিকার সাথে তাদের একত্রিত করি:
সেক্ষেত্রে next
সূচকটি হয় নোড অপসারণ করা হলে পরবর্তী ফ্রি সূচকের দিকে নির্দেশ করে বা নোড অপসারণ না করা হলে পরবর্তী ব্যবহৃত সূচকটি নির্দেশ করে।
এবং এই দিনগুলিতে লিঙ্কযুক্ত তালিকার জন্য আমি এক নম্বর ব্যবহারের কেস খুঁজে পাই। যখন আমরা সংরক্ষণ করতে চাই, বলি, মিলিয়ন ভেরিয়েবল-দৈর্ঘ্যের সাব-সিকোয়েন্সগুলি গড়ে গড়ে, বলুন, প্রতিটি 4 টি উপাদান (তবে কখনও কখনও উপাদানগুলি সরিয়ে ফেলা হয় এবং এই সাব-সিকোয়েন্সগুলির মধ্যে একটিতে যুক্ত করা হয়), লিঙ্কযুক্ত তালিকাটি আমাদের 4 মিলিয়ন সঞ্চয় করার অনুমতি দেয় লিঙ্কযুক্ত তালিকার নোডগুলি মিলিয়ন মিলিয়ন কনটেইনার পরিবর্তে পৃথক পৃথকভাবে গাদা-বরাদ্দযুক্ত: একটি দৈত্য ভেক্টর, অর্থাৎ দশ মিলিয়ন ছোট নয়।