সি ++ ভাষার ক্ষেত্রে নির্দিষ্ট উদ্বেগ
প্রথমত, C ++ দ্বারা আদেশিত কোনও তথাকথিত "স্ট্যাক" বা "হিপ" বরাদ্দ নেই । আপনি যদি ব্লক স্কোপগুলিতে স্বয়ংক্রিয় বস্তুর কথা বলছেন তবে সেগুলি এমনকি "বরাদ্দ" হয় না। (বিটিডাব্লু, সিতে স্বয়ংক্রিয় স্টোরেজ সময়কাল অবশ্যই "বরাদ্দকৃত" সমান নয়; পরবর্তীটি সি ++ পার্লেন্সে "গতিশীল" হয়।) গতিশীলভাবে বরাদ্দ হওয়া মেমরিটি ফ্রি স্টোরে রয়েছে , প্রয়োজনীয়ভাবে "হিপ"-তে নেই, যদিও দ্বিতীয়টি প্রায়শই (ডিফল্ট) বাস্তবায়ন হয় ।
যদিও বিমূর্ত মেশিনের সিনমেটিক নিয়ম অনুসারে, স্বয়ংক্রিয় বস্তুগুলি এখনও মেমরি দখল করে, একটি সিদ্ধিকৃত সি ++ বাস্তবায়ন যখন এই বিষয়টির প্রমাণ দেয় না তখন (যখন এটি প্রোগ্রামের পর্যবেক্ষণযোগ্য আচরণকে পরিবর্তন করে না) প্রমাণ করতে পারে এ বিষয়টিটিকে এড়িয়ে যাওয়ার অনুমতি দেওয়া হয়। এই অনুমতিটি আইএসও সি ++ -তে নিয়ম অনুসারে মঞ্জুর করা হয়েছে , এটি সাধারণ অনুচ্ছেদও সাধারণ অপটিমাইজেশন সক্ষম করে (এবং আইএসও সি-তেও প্রায় একই নিয়ম রয়েছে)। আস-বিধি বিধি ছাড়াও, আইএসও সি ++ এরও অনুলিপি সংক্রান্ত নিয়ম রয়েছেঅবজেক্টের নির্দিষ্ট সৃষ্টি বাদ দেওয়ার অনুমতি দিতে to এতে যুক্ত কন্সট্রাক্টর এবং ডেস্ট্রাক্টর কলগুলি বাদ দেওয়া হয়। ফলস্বরূপ, উত্স কোড দ্বারা ইঙ্গিত নিষ্পাপ বিমূর্ত শব্দার্থবিজ্ঞানের তুলনায় এই নির্মাতা এবং ধ্বংসকারীদের মধ্যে স্বয়ংক্রিয় বস্তুগুলি (যদি থাকে তবে )ও নির্মূল করা হয় eliminated
অন্যদিকে, ফ্রি স্টোর বরাদ্দ অবশ্যই ডিজাইনের দ্বারা "বরাদ্দ"। আইএসও সি ++ নিয়মের অধীনে এই জাতীয় বরাদ্দ কোনও বরাদ্দ ক্রিয়াকলাপের মাধ্যমে অর্জন করা যেতে পারে । যাইহোক, আইএসও সি ++ ১৪ এর পরে, একটি::operator new
নির্দিষ্ট ক্ষেত্রে বিশ্বব্যাপী বরাদ্দকরণ ফাংশন (অর্থাত্ ) কলগুলি মার্জ করার অনুমতি দেওয়ার জন্য একটি নতুন (অ-হিসাবে-যেমন) বিধি রয়েছে । সুতরাং গতিশীল বরাদ্দকরণ ক্রিয়াকলাপগুলির অংশগুলি স্বয়ংক্রিয় বস্তুর ক্ষেত্রেও কোনও বিকল্প হতে পারে।
বরাদ্দ ফাংশন মেমরির সংস্থান বরাদ্দ করে। বরাদ্দকারীদের ব্যবহার করে বরাদ্দের ভিত্তিতে অবজেক্টগুলি আরও বরাদ্দ করা যেতে পারে। স্বয়ংক্রিয় বস্তুর জন্য এগুলি সরাসরি উপস্থাপিত হয় - যদিও অন্তর্নিহিত মেমরিটি অ্যাক্সেস করা যায় এবং অন্যান্য বস্তুগুলিকে (স্থান দ্বারা new
) মেমরি সরবরাহ করতে ব্যবহৃত হতে পারে তবে এটি ফ্রি স্টোর হিসাবে দুর্দান্ত বোঝায় না, কারণ সরানোর কোনও উপায় নেই because অন্যত্র সংস্থান।
অন্যান্য সমস্ত উদ্বেগগুলি সি ++ এর আওতার বাইরে। তবুও, তারা এখনও তাৎপর্যপূর্ণ হতে পারে।
সি ++ এর বাস্তবায়ন সম্পর্কে
সি ++ রিফাইড অ্যাক্টিভেশন রেকর্ডস বা কিছু ধরণের প্রথম শ্রেণির ধারাবাহিকতা (যেমন বিখ্যাত দ্বারা call/cc
) প্রকাশ করে না, অ্যাক্টিভেশন রেকর্ড ফ্রেমগুলি সরাসরি পরিচালনা করার কোনও উপায় নেই - যেখানে বাস্তবায়নের জন্য স্বয়ংক্রিয় বস্তুগুলিকে স্থাপন করা দরকার। অন্তর্নিহিত বাস্তবায়ন ("নেটিভ" নন-পোর্টেবল কোড যেমন ইনলাইন এসেম্বলি কোড) এর সাথে কোনও (অ-বহনযোগ্য) আন্তঃব্যবস্থাগুলি না হয়ে গেলে ফ্রেমের অন্তর্নিহিত বরাদ্দ বাদ দেওয়া বেশ তুচ্ছ হতে পারে। উদাহরণস্বরূপ, যখন ডাকা ফাংশনটি ইনলাইন করা হয় তখন ফ্রেমগুলি কার্যকরভাবে অন্যদের মধ্যে মিশে যায়, সুতরাং "বরাদ্দ" কী তা দেখানোর কোনও উপায় নেই।
যাইহোক, একবার ইন্টারপগুলি সম্মানিত হয়ে গেলে জিনিসগুলি জটিল হয়ে উঠছে। সি ++ এর একটি সাধারণ বাস্তবায়ন দেশীয় (আইএসএ-স্তরীয় মেশিন) কোডের সাথে বাইনারি সীমানা ভাগ করে নেওয়া কিছু কলিং কনভেনশনের সাথে আইএসএ (নির্দেশনা-স্থিতি স্থাপত্য) -এ ইন্টারপ করার ক্ষমতা প্রকাশ করবে । এটি স্পষ্টভাবে ব্যয়বহুল হবে, উল্লেখযোগ্যভাবে, স্ট্যাক পয়েন্টারটি বজায় রাখার সময় , যা প্রায়শই সরাসরি আইএসএ-স্তরের রেজিস্টারে থাকে (সম্ভবত অ্যাক্সেসের জন্য নির্দিষ্ট মেশিনের নির্দেশাবলী সহ)। স্ট্যাক পয়েন্টারটি (বর্তমানে সক্রিয়) ফাংশন কলের শীর্ষ ফ্রেমের সীমানা নির্দেশ করে। যখন কোনও ফাংশন কল প্রবেশ করা হয়, তখন একটি নতুন ফ্রেম প্রয়োজন হয় এবং স্ট্যাক পয়েন্টারটি প্রয়োজনীয় ফ্রেমের আকারের চেয়ে কম নয় এমন একটি মান দ্বারা যুক্ত বা বিয়োগ করা হয় (আইএসএর কনভেনশনের উপর নির্ভর করে) t ফ্রেমটি তখন বরাদ্দকৃত বলা হয়অপারেশন পরে যখন স্ট্যাক পয়েন্টার। কলের জন্য ব্যবহৃত কলিং কনভেনশনের উপর নির্ভর করে ফাংশনগুলির প্যারামিটারগুলি স্ট্যাক ফ্রেমেও পাস করা যেতে পারে। ফ্রেমটি সি ++ উত্স কোড দ্বারা নির্দিষ্ট স্বয়ংক্রিয় বস্তুর (সম্ভবত প্যারামিটার সহ) মেমরি ধরে রাখতে পারে। এই জাতীয় বাস্তবায়নের অর্থে, এই বিষয়গুলি "বরাদ্দ" করা হয়। যখন কন্ট্রোলটি ফাংশন কল থেকে প্রস্থান করে, ফ্রেমের আর প্রয়োজন হয় না, সাধারণত কল করার আগে স্ট্যাক পয়েন্টারটিকে পুনরায় অবস্থায় ফিরিয়ে আনা হয় (কলিং কনভেনশন অনুযায়ী পূর্বে সংরক্ষণ করা হয়েছিল)। এটি "অবনতি" হিসাবে দেখা যেতে পারে। এই ক্রিয়াকলাপগুলি কার্যকরভাবে একটি LIFO ডেটা কাঠামো সক্রিয়করণ রেকর্ড করে তোলে, তাই এটি প্রায়শই " দ্য (কল) স্ট্যাক " নামে পরিচিত ।
যেহেতু বেশিরভাগ সি ++ বাস্তবায়ন (বিশেষত আইএসএ-স্তরীয় নেটিভ কোডকে টার্গেট করে এবং এসেম্বলি ভাষাটিকে তার তাত্ক্ষণিক আউটপুট হিসাবে ব্যবহার করে) এই জাতীয় কৌশলগুলি ব্যবহার করে, এই জাতীয় একটি বিভ্রান্তিকর "বরাদ্দ" প্রকল্পটি জনপ্রিয়। এই জাতীয় বরাদ্দ (পাশাপাশি deallocations) মেশিন চক্র ব্যয় করে এবং এটি ব্যয়বহুল হতে পারে যখন (অ-অনুকূলিতকরণ) কলগুলি ঘন ঘন ঘটে, যদিও আধুনিক সিপিইউ মাইক্রোআরকিটেক্টরগুলিতে সাধারণ কোড প্যাটার্নের জন্য হার্ডওয়ার দ্বারা প্রয়োগ করা জটিল অপ্টিমাইজেশন থাকতে পারে (যেমন ব্যবহার করার মতো) প্রয়োগ / নির্দেশাবলীতে স্ট্যাক ইঞ্জিন )।PUSH
POP
তবে যাইহোক, সাধারণভাবে, এটি সত্য যে স্ট্যাক ফ্রেমের বরাদ্দের ব্যয়টি ফ্রি স্টোর পরিচালনা করে এমন বরাদ্দ ফাংশনের কলের তুলনায় উল্লেখযোগ্যভাবে কম (যদি এটি সম্পূর্ণ অপটিমাইজড না হয়) , যা নিজেই কয়েকশো (যদি লক্ষ লক্ষ না হয়) থাকতে পারে :-) স্ট্যাক পয়েন্টার এবং অন্যান্য রাজ্য বজায় রাখার জন্য ক্রিয়াকলাপ। বরাদ্দ ফাংশন সাধারণত হোস্ট করা পরিবেশ দ্বারা সরবরাহ করা API এর উপর ভিত্তি করে (যেমন ওএস দ্বারা সরবরাহিত রানটাইম)। ফাংশন কলগুলির জন্য স্বয়ংক্রিয় অবজেক্টগুলি ধারণ করার উদ্দেশ্য থেকে পৃথক, এই জাতীয় বরাদ্দগুলি সাধারণ-উদ্দেশ্যযুক্ত, তাই তাদের স্ট্যাকের মতো ফ্রেম কাঠামো থাকবে না। Ditionতিহ্যগতভাবে, তারা পুল স্টোরেজ থেকে হ্যাপ (বা বেশ কয়েকটি হ্যাপ ) নামে স্থান বরাদ্দ করে । "স্ট্যাক" থেকে আলাদা, এখানে ধারণা "হিপ" ডেটা কাঠামোটি ব্যবহৃত হচ্ছে তা নির্দেশ করে না;এটি বহু দশক আগে প্রাথমিক ভাষা প্রয়োগ থেকে উদ্ভূত । (বিটিডাব্লু, কল স্ট্যাকটি সাধারণত প্রোগ্রাম বা থ্রেড স্টার্টআপে পরিবেশ দ্বারা গাদা থেকে স্থির বা ব্যবহারকারী-নির্দিষ্ট আকারের সাথে বরাদ্দ করা হয়)) ব্যবহারের কেসগুলির প্রকৃতি একগাদা থেকে বরাদ্দ এবং ডিএলোকেশনগুলি আরও জটিল করে তোলে (ধাক্কা বা পপ এর চেয়ে বেশি) স্ট্যাক ফ্রেম), এবং হার্ডওয়ার দ্বারা সরাসরি অনুকূলিত হওয়া খুব কমই সম্ভব।
মেমোরি অ্যাক্সেসের উপর প্রভাব
সাধারণ স্ট্যাক বরাদ্দ সর্বদা নতুন ফ্রেমটিকে শীর্ষে রাখে, সুতরাং এটির বেশ ভাল লোকাল রয়েছে। এটি ক্যাশে বন্ধুত্বপূর্ণ। ওটিওএইচ, ফ্রি স্টোর এলোমেলোভাবে বরাদ্দ মেমরির এমন কোনও সম্পত্তি নেই। আইএসও সি ++ 17 হ'ল, এখানে পুলের সংস্থান টেম্পলেট সরবরাহ করা আছে <memory>
। এই জাতীয় ইন্টারফেসের প্রত্যক্ষ উদ্দেশ্য হ'ল একটানা বরাদ্দের ফলাফলগুলি মেমরির সাথে একত্রে হওয়া। এটি এই সত্যটি স্বীকার করে যে এই কৌশলটি সমসাময়িক বাস্তবায়নগুলির সাথে পারফরম্যান্সের জন্য সাধারণত ভাল, যেমন আধুনিক স্থাপত্যগুলিতে ক্যাশে বন্ধুত্বপূর্ণ। এটি বরাদ্দ না করে অ্যাক্সেসের কর্মক্ষমতা সম্পর্কে ।
concurrency
মেমরির একযোগে অ্যাক্সেসের প্রত্যাশা স্ট্যাক এবং হিপগুলির মধ্যে পৃথক প্রভাব ফেলতে পারে। একটি কল স্ট্যাক সাধারণত সি ++ বাস্তবায়নে মৃত্যুর এক থ্রেডের দ্বারা একচেটিয়াভাবে মালিকানাধীন। OTOH, হ্যাপগুলি প্রায়শই একটি প্রক্রিয়াতে থ্রেডগুলির মধ্যে ভাগ করা হয় । এই জাতীয় স্তূপগুলির জন্য, বরাদ্দ এবং অবনতি ফাংশনগুলিকে ভাগ করা অভ্যন্তরীণ প্রশাসনিক ডেটা কাঠামোটিকে ডেটা রেস থেকে রক্ষা করতে হয়। ফলস্বরূপ, অভ্যন্তরীণ সিঙ্ক্রোনাইজেশন ক্রিয়াকলাপগুলির কারণে গাদা বরাদ্দ এবং ডিএলোকেশনের অতিরিক্ত ওভারহেড থাকতে পারে।
স্থান দক্ষতা
ব্যবহারের ক্ষেত্রে এবং অভ্যন্তরীণ ডেটা স্ট্রাকচারের প্রকৃতির কারণে, স্তূপগুলি অভ্যন্তরীণ মেমরি খণ্ডিত হতে পারে , যখন স্ট্যাকটি তা করে না। এটি মেমোরি বরাদ্দের কর্মক্ষমতা উপর সরাসরি প্রভাব ফেলবে না, তবে ভার্চুয়াল মেমরি সহ একটি সিস্টেমে কম স্থান দক্ষতা স্মৃতি অ্যাক্সেসের সামগ্রিক কর্মক্ষমতা হ্রাস করতে পারে। এইচডিডি শারীরিক মেমরির অদলবদল হিসাবে ব্যবহৃত হয় এটি বিশেষত ভয়ঙ্কর। এটি বেশ দীর্ঘ বিলম্বের কারণ হতে পারে - কখনও কখনও কোটি কোটি চক্র।
স্ট্যাক বরাদ্দের সীমাবদ্ধতা
যদিও বাস্তবে স্তরের বরাদ্দের তুলনায় স্ট্যাক বরাদ্দগুলি প্রায়শই কার্যক্ষমতায় উন্নত হয় তবে এর অর্থ এই নয় যে স্ট্যাক বরাদ্দ সর্বদা হিপ বরাদ্দ প্রতিস্থাপন করতে পারে।
প্রথমত, আইএসও সি ++ এর সাথে পোর্টেবল উপায়ে রানটাইমের সময় নির্দিষ্ট আকারের সাথে স্ট্যাকের জন্য জায়গা বরাদ্দ করার কোনও উপায় নেই। alloca
G ++ এর ভিএলএ (ভেরিয়েবল-দৈর্ঘ্যের অ্যারে) এর মতো বাস্তবায়ন দ্বারা সরবরাহ করা এক্সটেনশন রয়েছে তবে সেগুলি এড়াতে কারণ রয়েছে। (আইআইআরসি, লিনাক্স উত্সটি সম্প্রতি ভিএলএর ব্যবহার সরিয়ে ফেলেছে।) (এছাড়াও নোট করুন যে সিএসও সি৯৯-এ ভিএলএন্ডের বাধ্যবাধকতা রয়েছে, তবে আইএসও সি 11 সমর্থনটি optionচ্ছিকভাবে পরিণত করে।)
দ্বিতীয়ত, স্ট্যাক স্পেস ক্লান্তি সনাক্ত করার জন্য কোনও নির্ভরযোগ্য এবং বহনযোগ্য উপায় নেই। এটিকে প্রায়শই স্ট্যাক ওভারফ্লো (এইচএমএম, এই সাইটের ব্যুৎপত্তি) বলা হয় তবে সম্ভবত আরও সঠিকভাবে স্ট্যাককে ছাড়িয়ে যায় । বাস্তবে, এটি প্রায়শই অবৈধ মেমরি অ্যাক্সেসের কারণ হয়ে থাকে এবং প্রোগ্রামের অবস্থাটি তখন দুর্নীতিগ্রস্থ হয় (... বা আরও খারাপ হতে পারে, একটি সুরক্ষা গর্ত)। আসলে, আইএসও সি ++ এর "স্ট্যাক" সম্পর্কে কোনও ধারণা নেই এবং সংস্থানটি শেষ হয়ে গেলে এটিকে অপরিজ্ঞাত আচরণ করে তোলে । স্বয়ংক্রিয় অবজেক্টগুলির জন্য কতটা জায়গা রেখে দেওয়া উচিত সে সম্পর্কে সতর্ক হন।
যদি স্ট্যাকের জায়গাটি শেষ হয়ে যায়, স্ট্যাকের মধ্যে অনেকগুলি বরাদ্দ রয়েছে, যা ফাংশনগুলির অনেক বেশি সক্রিয় কল বা স্বয়ংক্রিয় বস্তুর অযাচিত ব্যবহারের কারণে হতে পারে। এই জাতীয় কেসগুলি বাগের অস্তিত্বের পরামর্শ দিতে পারে, যেমন সঠিক প্রস্থান শর্ত ছাড়া একটি পুনরাবৃত্ত ফাংশন কল।
তবুও, গভীর পুনরাবৃত্তি কলগুলি কখনও কখনও পছন্দসই হয়। আনবাউন্ড অ্যাক্টিভ কলগুলির ভাষার সমর্থন প্রয়োজন এমন ভাষার প্রয়োগে (যেখানে কলটির গভীরতা কেবলমাত্র সম্পূর্ণ স্মৃতি দ্বারা সীমাবদ্ধ), সাধারণ সি ++ বাস্তবায়নগুলির মতো লক্ষ্য ভাষা অ্যাক্টিভেশন রেকর্ড হিসাবে সরাসরি (সমসাময়িক) নেটিভ কল স্ট্যাকটি ব্যবহার করা অসম্ভব । সমস্যাটি সমাধান করার জন্য, অ্যাক্টিভেশন রেকর্ড নির্মাণের বিকল্প উপায়গুলি প্রয়োজন। উদাহরণস্বরূপ, এসএমএল / এনজে স্পষ্টভাবে গাদাতে ফ্রেম বরাদ্দ করে এবং ক্যাকটাস স্ট্যাক ব্যবহার করে । এই ধরনের অ্যাক্টিভেশন রেকর্ড ফ্রেমের জটিল বরাদ্দ সাধারণত কল স্ট্যাক ফ্রেমের তত দ্রুত হয় না। যাইহোক, যদি এই জাতীয় ভাষাগুলি যথাযথ পুচ্ছ পুনরাবৃত্তির গ্যারান্টি সহ আরও প্রয়োগ করা হয়, অবজেক্ট ল্যাঙ্গুয়েজে সরাসরি স্ট্যাক বরাদ্দ (অর্থাত্ ভাষায় "অবজেক্ট" রেফারেন্স হিসাবে সংরক্ষণ করা হয় না, তবে নেটিভ আদিম মানগুলি যা ভাগ না করা সি ++ অবজেক্টগুলিতে এক থেকে এক ম্যাপ করা যায়) আরও বেশি জটিল সাধারণভাবে কর্মক্ষমতা জরিমানা। এই জাতীয় ভাষা বাস্তবায়নের জন্য সি ++ ব্যবহার করার সময়, পারফরম্যান্সের প্রভাবগুলি অনুমান করা শক্ত is