পয়েন্টার ভেরিয়েবলগুলির ব্যবহার কি একটি মেমরির ওভারহেড নয়?


29

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


11
গতিশীল মেমরি বরাদ্দের সুবিধাগুলি পয়েন্টারের ব্যয়কে ছাড়িয়ে যায়।
জেমস ম্যাকলিউড

32
আপনি কীভাবে অন্য ভাষা (জাভা, সি #, ...) অবজেক্টের জন্য রেফারেন্স ভাবেন? (ইঙ্গিত: তারা পয়েন্টার ব্যবহার করে)।
এরিক tদ

6
একটি পয়েন্টার রেজিস্টারগুলিতে বসতে পারে বা তর্ক হিসাবে পাস হতে পারে। উভয় ক্ষেত্রেই ওভারহেডের কোনও সুস্পষ্ট স্মৃতি নেই । এবং পয়েন্টারটি গণনা করা যেতে পারে (উদাহরণস্বরূপ পয়েন্টার পাটিগণিত, ফাংশন রিটার্নিং পয়েন্টার ইত্যাদি)
বেসিল স্টারিনকিভিচ

9
ঠিকানার মাধ্যমে কোনও (বৃহত) স্ট্রাক্ট আর্গুমেন্ট কীভাবে পাস করবেন ? যদি আপনি এটি পয়েন্টার ভেরিয়েবল হিসাবে গণনা করেন তবে এটি অনেক অ্যালগরিদমের পক্ষে অনিবার্য, এবং মান দ্বারা স্ট্রাক্ট পাস করার চেয়ে অনেক কম জায়গা ব্যবহার করে!
পিজেট্রাইল

4
এটি কিছু কিছু হোমওয়ার্ক অ্যাসাইনমেন্ট অনুভূতি আছে। উত্তরটি পয়েন্টারগুলি বোঝে এবং সেগুলি কীভাবে ব্যবহৃত হয় তা যদি অনুসন্ধানের জন্য তৈরি করা হয়।
মাইকেল শ

উত্তর:


34

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

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

এছাড়াও, জোশুয়া টেলর একটি মন্তব্যে আমাদের মনে করিয়ে দেওয়ার সাথে সাথে, পয়েন্টারগুলি রেফারেন্সের মাধ্যমে কিছু পাস করার জন্য ব্যবহৃত হয়। উদাহরণস্বরূপ, struct foo f; init_foo(&f);স্ট্যাকের উপর চ বরাদ্দ হবে এবং তারপরে init_foo()একটি পয়েন্টার সহ কল করবে struct। এটা খুব সাধারণ। (কেবলমাত্র এই পয়েন্টারগুলিকে ""র্ধ্বমুখী" পাস না করার জন্য সতর্ক থাকুন foo&) মেমরি একই পরিমাণ।

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

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

সুতরাং, পয়েন্টার হয় না শুধুমাত্র সময়-সমালোচনামূলক, কম মেমরি অ্যাপ্লিকেশন ব্যবহার করা হয়, তারা ব্যবহার করা হয় সর্বত্র


5
"পয়েন্টারগুলি কেন ব্যবহৃত হচ্ছে তার প্রধান কারণটি গতিশীল মেমরি বরাদ্দের জন্য" এটি সি ++ এর ক্ষেত্রে হতে পারে তবে সি তে হয় না, সি-তে পয়েন্টারগুলি আপনার রেফারেন্সের মাধ্যমে কোনও কিছু পাস করার একমাত্র উপায় are আপনি যদি একটি সম্পূর্ণ কাঠামো অনুলিপি করতে না চান তবে আপনার এটিতে একটি পয়েন্টার লাগবে। আপনি কোনও গতিশীল বরাদ্দ আদৌ না করে থাকলেও এটি এখনও বোঝা যায়। উদাহরণস্বরূপ, স্ট্যাকের উপর struct foo f; init_foo(&f);বরাদ্দ হবে fএবং তারপরে init_fooসেই স্ট্রাক্টটিতে একটি পয়েন্টার সহ কল করবে । এটা খুব সাধারণ। (এই পয়েন্টারগুলিকে "upর্ধ্বমুখী" পাস না করার জন্য কেবল সাবধান হন))
জোশুয়া টেলর

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

যাইহোক এটি আপনার উত্তর যুক্ত করুন। :)
জোশুয়া টেলর

2
এটি এবং নিজের মধ্যে যথেষ্ট পরিমাণে ওভারহেড উপস্থাপন করে, কারণ এই ব্লকে একটি (লুকানো) শিরোনাম থাকবে যা সাধারণত কয়েকটি পয়েন্টার হিসাবে বড় হবে। => প্রকৃতপক্ষে, আধুনিক প্রয়োগগুলির mallocখুব কম হেডার ওভারহেড রয়েছে কারণ তারা "বালতিগুলিতে" বরাদ্দকৃত ব্লকগুলি ক্লাস্টার করে। অন্যদিকে, এটি সাধারণভাবে অতিরিক্ত বরাদ্দে অনুবাদ করে: আপনি 35 বাইট চেয়েছেন এবং 64 টি (আপনার জ্ঞান ছাড়াই) এভাবে 29 টি নষ্ট করছেন ...
ম্যাথিউ এম।

1
@ মাইকনাকিস: আরও ভাল লাগছে, আমার সাথে লেগে থাকার জন্য ধন্যবাদ :)
ম্যাথিউ এম।

35

সুতরাং এটি কি একটি স্মৃতি ওভারহেড নয়?

অবশ্যই, একটি অতিরিক্ত ঠিকানা (সাধারণত প্রসেসরের উপর নির্ভর করে 4/8 বাইট)।

কীভাবে ক্ষতিপূরণ দেওয়া হয়?

এইটা না. যদি আপনাকে পয়েন্টারগুলির জন্য প্রয়োজনীয় দিকনির্দেশের প্রয়োজন হয় তবে তার জন্য আপনাকে অর্থ প্রদান করতে হবে।

পয়েন্টারগুলি কি সমালোচনামূলক কম মেমোরি অ্যাপ্লিকেশনগুলিতে ব্যবহৃত হয়?

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


1
@ ডেভিডগ্রিনবার্গ এটি কেবল ধরে নিচ্ছে যে কোনও রিটার্ন মান অপ্টিমাইজেশন নেই
দারখোগ

3
আশির দশকে 15 কে পিছনে ফিট থাকতে হবে এমন ডসের জন্য টিএসআর অ্যাপ্লিকেশনগুলি লেখার সময় আমি পয়েন্টার ব্যবহার করেছি used সুতরাং হ্যাঁ, এগুলি লো-মেমরি অ্যাপ্লিকেশনগুলিতে ব্যবহৃত হয়।
রোবটটি

1
@ স্টেভেনবার্ন্যাপ আপনি কি কোনও টিএসআর অ্যাপ্লিকেশনের জন্য 15 কে লো মেমোরি কল করেন? আমি একবার একটি টিএসআর সরঞ্জাম লিখেছিলাম যা কেবলমাত্র 16 বাইট মেমরি গ্রাস করে।
ক্যাস্পারড

22
@ ক্যাস্পার্ড: এবং আমার দিনে ফিরে, আমাদের কেবল শূন্য ছিল
জ্যাক

3
@ জ্যাক dilbert.com/strip/1992-09-08
edc65

11

টেলাস্টিনের মতো আমার এইরকম স্পিন নেই।

এম্বেড থাকা প্রসেসরে সিস্টেম গ্লোবালগুলি নির্দিষ্ট, হার্ড-কোডেড ঠিকানা দিয়ে সম্বোধন করা যেতে পারে।

কোনও প্রোগ্রামের গ্লোবালগুলিকে একটি বিশেষ পয়েন্টার থেকে অফসেট হিসাবে সম্বোধন করা হবে যা গ্লোবাল এবং স্ট্যাটিকস সংরক্ষণ করা মেমরির স্থানটির দিকে নির্দেশ করে।

কোনও ফাংশন প্রবেশ করানো হয় এবং অন্য বিশেষ পয়েন্টার থেকে অফসেট হিসাবে সম্বোধন করা হলে স্থানীয় ভেরিয়েবলগুলি উপস্থিত হয়, প্রায়শই তাকে "ফ্রেম পয়েন্টার" বলা হয়। এটি ফাংশনে যুক্তিগুলি অন্তর্ভুক্ত করে। যদি আপনি স্ট্যাক পয়েন্টারটির সাথে ধাক্কা ও পপগুলি সম্পর্কে সতর্ক হন তবে আপনি ফ্রেম পয়েন্টারটি সরিয়ে স্ট্যাক পয়েন্টার থেকে সরাসরি স্থানীয় ভেরিয়েবলগুলি অ্যাক্সেস করতে পারেন।

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


6

হ্যা অবশ্যই. তবে এটি ভারসাম্যপূর্ণ কাজ।

লো মেমরি অ্যাপ্লিকেশনগুলি সাধারণত কোনও পয়েন্টার ভেরিয়েবলের ওভারহেডের মধ্যে ট্রেড অফকে বিবেচনা করে তৈরি করা হবে যা ওভারহেডের তুলনায় একটি বিশাল প্রোগ্রাম হবে (যা অবশ্যই স্মৃতিতে সংরক্ষণ করতে হবে, মনে রাখবেন!) যদি পয়েন্টার ব্যবহার না করা যায় তবে ।

এই বিবেচনাটি সমস্ত প্রোগ্রামের জন্য প্রযোজ্য , কারণ কেউ ডুপ্লিকেট কোড বাম ডান এবং কেন্দ্রের সহিত কোনও হররড তৈরি করতে চায় না, অপরিণামযোগ্য জগাখিচুড়ি, এটি হওয়া দরকারের চেয়ে বিশগুণ বেশি।


5

সি এবং সি ++ এর মতো ভাষায়, ভেরিয়েবলগুলিতে পয়েন্টার ব্যবহার করার সময় সেই ঠিকানাটি সঞ্চয় করার জন্য আমাদের আরও একটি মেমরি অবস্থান প্রয়োজন। সুতরাং এটি কি একটি স্মৃতি ওভারহেড নয়?

আপনি ধরে নিলেন যে পয়েন্টারটি সঞ্চয় করা দরকার। এটা সবসময় হয় না। প্রতিটি ভেরিয়েবল কিছু মেমরি ঠিকানায় সংরক্ষণ করা হয়। বলুন আপনি longহিসাবে ঘোষণা করেছেন long n = 5L;। এটি nকোনও ঠিকানার জন্য সঞ্চয়স্থান বরাদ্দ করে । আমরা সেই ঠিকানাটি ব্যবহার করার মতো অভিনব জিনিসগুলি করতে চাই *((char *) &n) = (char) 0xFF;যাতে কিছু অংশগুলি পরিচালনা করতে পারি nnঅতিরিক্ত ওভারহেড হিসাবে ঠিকানাটি কোথাও সঞ্চিত নয়।

কীভাবে ক্ষতিপূরণ দেওয়া হয়?

এমনকি যদি পয়েন্টারগুলি স্পষ্টরূপে সংরক্ষণ করা হয় (যেমন তালিকার মতো ডেটা স্ট্রাকচারে), ফলস্বরূপ ডেটা স্ট্রাকচারটি প্রায়শই পয়েন্টার ব্যতীত সমতুল্য ডেটা কাঠামোর চেয়ে আরও মার্জিত (সহজ, বোঝা সহজ, হ্যান্ডেল করা সহজ, ইত্যাদি)।

পয়েন্টারগুলি কি সমালোচনামূলক কম মেমোরি অ্যাপ্লিকেশনগুলিতে ব্যবহৃত হয়?

হ্যাঁ। মাইক্রো-কন্ট্রোলারগুলি ব্যবহার করে এমন ডিভাইসগুলিতে প্রায়শই খুব কম স্মৃতি থাকে তবে ফার্মওয়্যার বিঘ্নিত ভেক্টর বা বাফার পরিচালনা ইত্যাদি পরিচালনা করার জন্য পয়েন্টার ব্যবহার করতে পারে etc.


কিছু ভেরিয়েবল মেমোরিতে সংরক্ষণ করা হয় না, তবে কেবল রেজিস্টারে থাকে
বেসাইল স্টারিনকিভিচ

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

সংকলকটিকে কেবল স্থানীয় রেজিস্টারগুলিতে কিছু স্থানীয় ভেরিয়েবল সংরক্ষণ করার অনুমতি দেওয়া হতে পারে এবং বেশিরভাগ অপ্টিমাইজ করাgcc -fverbose-asm -S -O2
সংকলকরা

@ বেসাইলস্টারিঙ্কেভিচ আপনি যে পর্যবেক্ষণটি দিয়ে পর্যালোচনা করে যাচ্ছেন যে ভেরিয়েবলগুলি নিখুঁতভাবে রেজিস্টারে সংরক্ষণ করা যেতে পারে তার বিষয়ে আমি নিশ্চিত নই। আপনি দয়া করে বিস্তারিত বলতে পারেন?
লরেন্স

5

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

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

এমনকি আপনার সাধারণ ভেরিয়েবলগুলির প্রতীক টেবিলটিতে একটি প্রবেশ রয়েছে যা আপনার ভেরিয়েবলটির দিকে ইশারা করছে এমন ঠিকানা সংরক্ষণ করে। সুতরাং, আমি মনে করি না এটি মেমরির ক্ষেত্রে (মাত্র 4 বা 8 বাইট) বেশি ওভারহেড তৈরি করে। এমনকি জাভা জাতীয় ভাষাগুলি অভ্যন্তরীণভাবে পয়েন্টার ব্যবহার করে (রেফারেন্স), তারা আপনাকে এগুলি চালিত করতে দেয় না কারণ এটি জেভিএমকে কম সুরক্ষিত করে তুলবে।

আপনার পয়েন্টারগুলি কেবল তখনই ব্যবহার করা উচিত যখন আপনার কাছে অন্য কোনও পছন্দ নেই যেমন ডেটা-প্রকার, কাঠামোগুলি (গ) যেমন পয়েন্টার ব্যবহার করা ত্রুটি হতে পারে যদি সঠিকভাবে পরিচালনা না করা হয় এবং তুলনামূলকভাবে ডিবাগ করা শক্ত হয়।


3

সুতরাং এটি কি একটি স্মৃতি ওভারহেড নয়?

হ্যাঁ .... না ... হতে পারে?

এটি একটি বিশ্রী প্রশ্ন, কারণ মেশিনে মেমরির ঠিকানা সম্পর্কিত পরিসীমা কল্পনা করুন এবং এমন একটি সফ্টওয়্যার যা অবিচ্ছিন্নভাবে ট্র্যাক করে রাখা উচিত যে জিনিসগুলি মেমরিতে কীভাবে এমনভাবে স্ট্যাকের সাথে বেঁধে রাখা যায় না।

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

অডিও ডেটা কোথায় সঞ্চিত তা আমরা কীভাবে ট্র্যাক করব? আমাদের এটির একটি স্মৃতি ঠিকানা প্রয়োজন। প্রোগ্রামটি কেবল অডিও ডেটা খণ্ডকে মেমরির মধ্যে রাখে তা নয়, যেখানে এটি মেমরিতে থাকে সেগুলিও ট্র্যাক করে রাখা দরকার । সুতরাং আমাদের একটি মেমরি ঠিকানা (যেমন, একটি পয়েন্টার) প্রায় রাখা প্রয়োজন। এবং মেমরি ঠিকানার জন্য প্রয়োজনীয় স্টোরেজটির আকারটি মেশিনের ঠিকানা সীমার সাথে মিলিয়ে চলেছে (উদাহরণস্বরূপ: 64৪-বিট অ্যাড্রেসিং রেঞ্জের জন্য -৪-বিট পয়েন্টার)।

সুতরাং এটি "হ্যাঁ" ধরণের, এটির জন্য কোনও মেমরি ঠিকানার খোঁজ রাখার জন্য সঞ্চয়স্থান প্রয়োজন, তবে এটি এই জাতীয় গতিবেগের -র জন্য বরাদ্দকৃত মেমরির জন্য এড়াতে পারি না এমন নয়।

কীভাবে ক্ষতিপূরণ দেওয়া হয়?

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

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

পয়েন্টারগুলি কি সমালোচনামূলক কম মেমোরি অ্যাপ্লিকেশনগুলিতে ব্যবহৃত হয়?

হ্যাঁ, খুব সাধারণভাবে তাই হয়, হিসাবে অনেক কর্মক্ষমতা-সমালোচনামূলক অ্যাপ্লিকেশন C অথবা সি ++ যা পয়েন্টার ব্যবহার দ্বারা প্রভাবিত হয় লেখা হয় (তারা একটি স্মার্ট পয়েন্টার বা মত একটি ধারক পিছনে হতে পারে std::vectorবা std::stringকিন্তু অন্তর্নিহিত বলবিজ্ঞান একটি পয়েন্টার যা ব্যবহার করা হয় ফুটাইয়া কমান গতিশীল মেমরি ব্লকে ঠিকানার ট্র্যাক রাখতে)।

এখন এই প্রশ্নে ফিরে:

কীভাবে ক্ষতিপূরণ দেওয়া হয়? (অংশ দুই)

পয়েন্টারগুলি সাধারণত ময়লা সস্তার হয় যদি না আপনি সেগুলির দশ মিলিয়ন (যা এখনও 64৪-বিট মেশিনে একটি পরিমাপ * 8 মেগাবাইট)।

* নোট হিসাবে উল্লেখ করেছেন যে একটি "পরিমাপক" 8 ম্যাগ এখনও এল 3 ক্যাশে আকারের। এখানে আমি মোট ডিআরএএম ব্যবহারের অর্থে "পরিশ্রমী" বেশি ব্যবহার করেছি এবং মেমোরির সাথে সম্পর্কিত আপেক্ষিক আকারটি পয়েন্টারগুলির একটি স্বাস্থ্যকর ব্যবহার নির্দেশ করবে।

যেখানে পয়েন্টারগুলি ব্যয়বহুল হয় সেগুলি পয়েন্টারগুলি নয় তবে:

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

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

মেমরি অ্যাক্সেস

মেমরি অ্যাক্সেস হল অ্যালগরিদমের বাইরে পারফরম্যান্সের সবচেয়ে গুরুত্বপূর্ণ দিক aspects এএএ গেম ইঞ্জিনগুলির মতো প্রচুর পারফরম্যান্স-সমালোচনামূলক ক্ষেত্রগুলি তাদের শক্তির ডেটা-ভিত্তিক অনুকূলকরণের দিকে অনেক বেশি ফোকাস করে যা আরও দক্ষ মেমরি অ্যাক্সেসের নিদর্শন এবং বিন্যাসে ফোটায়।

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

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

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

অপ্রত্যক্ষভাবে পয়েন্টার অ্যাক্সেস অনুকূলিতকরণ

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

চারদিকে পয়েন্টারদের তাড়া করছে

ধরুন আমাদের কাছে এককভাবে লিঙ্কযুক্ত তালিকা রয়েছে:

Foo->Bar->Baz->null

সমস্যাটি হ'ল আমরা যদি এই সমস্ত নোডগুলি একটি সাধারণ-উদ্দেশ্য বরাদ্দকারী (এবং সম্ভবত সমস্ত একসাথে নয়) এর বিপরীতে আলাদাভাবে বরাদ্দ করি তবে আসল স্মৃতিটি কিছুটা এভাবে ছড়িয়ে দেওয়া হতে পারে (সরলীকৃত চিত্র):

এখানে চিত্র বর্ণনা লিখুন

আমরা যখন পয়েন্টারগুলির চারপাশে তাড়া শুরু করি এবং Fooনোডটি অ্যাক্সেস করি তখন আমরা একটি বাধ্যতামূলক মিস (এবং সম্ভবত একটি পৃষ্ঠা ত্রুটি) দিয়ে তার মেমরি অঞ্চল থেকে মেমরির ধীর অঞ্চলগুলি থেকে মেমরির দ্রুত অঞ্চলগুলিতে সরিয়ে নিয়ে শুরু করি:

এখানে চিত্র বর্ণনা লিখুন

এটি আমাদের কেবলমাত্র একটি অংশ অ্যাক্সেস করতে এবং এই তালিকাটির চারপাশে পয়েন্টারগুলি তাড়া করার সাথে সাথে বাকী অংশটি উচ্ছেদ করার জন্য একটি মেমরি অঞ্চলকে ক্যাশে (সম্ভবত পৃষ্ঠাটিও) রাখে causes মেমরি বরাদ্দকারীকে নিয়ন্ত্রণে রাখার মাধ্যমে, তবে আমরা এই জাতীয় একটি তালিকা স্বচ্ছতার সাথে বরাদ্দ করতে পারি:

এখানে চিত্র বর্ণনা লিখুন

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

* দ্রষ্টব্য: এটি মেমরির শ্রেণিবিন্যাস এবং রেফারেন্সের স্থানীয়তা সম্পর্কে একটি খুব বেশি চিত্রিত চিত্র এবং আলোচনা, তবে আশা করি এটি প্রশ্নের মাত্রার জন্য উপযুক্ত।


1
"মাপলি 8 মেগাবাইট" একটি আধুনিক সিপিইউতে পুরো এল 3 ক্যাশেটির সাধারণ আকার
বেন ভয়েগট

1
@ বেনওয়েগট আমি এটিকে কিছুটা কমিয়ে দেওয়ার চেষ্টা করব। অবশ্যই এটি ভয়াবহ হবে যদি প্রতিটি পয়েন্টারটি 32-বিট মেমরির অংশের দিকে ইঙ্গিত করে, যেমন

@ বেনওয়েগ্ট সেই অংশটি পরিষ্কার করার জন্য একটি পাদটীকা যুক্ত করেছেন!

এই স্পষ্টতা ভাল দেখাচ্ছে।
বেন ভয়েগট

1

সুতরাং এটি কি একটি স্মৃতি ওভারহেড নয়?

এটি প্রকৃতপক্ষে একটি স্মৃতি ওভারহেড, তবে খুব ছোট একটি (তুচ্ছতার দিকে)।

কীভাবে ক্ষতিপূরণ দেওয়া হয়?

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

পয়েন্টারগুলি কি সমালোচনামূলক কম মেমোরি অ্যাপ্লিকেশনগুলিতে ব্যবহৃত হয়?

হ্যাঁ।


0

আপনার কেবলমাত্র অতিরিক্ত মেমরির প্রয়োজন (পয়েন্টার প্রতি 4-8 বাইট, সাধারণত) যখন আপনার সেই পয়েন্টার প্রয়োজন হয়। এমন অনেক কৌশল রয়েছে যা এটিকে আরও সাশ্রয়ী করে তোলে।

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

অত্যন্ত কড়া স্মৃতি পরিস্থিতিতে, এটি ব্যয় হ্রাস করতে ব্যবহার করা যেতে পারে। আপনি যদি খুব আঁটসাঁট মেমোরি স্পেসে কাজ করছেন, আপনার সাধারণত কতগুলি জিনিস হস্তান্তর করতে হবে সে সম্পর্কে আপনার ভাল ধারণা রয়েছে। একবারে একগুচ্ছ পূর্ণসংখ্যার বরাদ্দ করা এবং তাদের কাছে সম্পূর্ণ পয়েন্টার রাখার পরিবর্তে আপনি আপনার বিকাশকারী জ্ঞানের সুবিধা নিতে পারেন যে এই নির্দিষ্ট অ্যালগরিদমে আপনার কখনও 256 এর বেশি পূর্ণসংখ্যার হবে না। সেক্ষেত্রে, আপনি প্রথম পূর্ণসংখ্যার দিকে একটি পয়েন্টার রাখতে পারেন এবং একটি পূর্ণ পয়েন্টার (4/8 বাইট) ব্যবহার না করে একটি চর (1 বাইট) ব্যবহার করে একটি সূচকের উপর নজর রাখতে পারেন। ফ্লাইতে এই সূচকগুলির কয়েকটি তৈরি করতে আপনি অ্যালগরিদমিক কৌশলগুলিও ব্যবহার করতে পারেন।

এই ধরণের স্মৃতি বিবেক অতীতে জনপ্রিয় ছিল। উদাহরণস্বরূপ, এনইএস গেমগুলি তাদের সমস্ত পাইকারি সঞ্চয় করার পরিবর্তে ডেটা ক্র্যাম করার ক্ষমতা এবং অ্যালগোরিদমিকভাবে পয়েন্টার উত্পন্ন করার উপর নির্ভর করে।

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

মৌলিকভাবে, আপনি ওভারহেডের সমস্ত থেকে মুক্তি পেতে পারবেন না। তবে আপনি এটি নিয়ন্ত্রণ করতে পারেন। অ্যালগরিদমিক কৌশলগুলি ব্যবহার করে আপনি সঞ্চয় করতে পারেন এমন পয়েন্টার সংখ্যা হ্রাস করতে পারবেন। আপনি যদি ডায়নামিক মেমোরিটিতে পয়েন্টার ব্যবহার করে থাকেন তবে আপনি কখনই সেই গতিশীল মেমরি স্পটে 1 পয়েন্টার রাখার ব্যয়ের চেয়ে কম পাবেন না, কারণ এটি মেমরির সেই ব্লকের কোনও অ্যাক্সেসের জন্য প্রয়োজনীয় সর্বনিম্ন পরিমাণের তথ্য information যাইহোক, আল্ট্রা-টাইট মেমরি সীমাবদ্ধ পরিস্থিতিতে, এটি বিশেষ ক্ষেত্রে হয়ে থাকে (গতিশীল মেমরি এবং অতি-টাইট মেমরির সীমাবদ্ধতা একই পরিস্থিতিতে উপস্থিত না হওয়ার প্রবণতা)।


0

অনেক পরিস্থিতিতে পয়েন্টার আসলে মেমরি বাঁচায়। পয়েন্টার ব্যবহারের একটি সাধারণ বিকল্প হ'ল ডেটা স্ট্রাকচারের একটি অনুলিপি তৈরি করা। ডেটা স্ট্রাকচারের একটি সম্পূর্ণ অনুলিপি পয়েন্টারের চেয়ে বড় হবে।

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

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.