সি ++ চঞ্চল কীওয়ার্ডটি কি কোনও মেমরি বেড়ের পরিচয় দেয়?


86

আমি বুঝতে পারি যে volatile সংকলককে অবহিত করে যে মানটি পরিবর্তিত হতে পারে, তবে এই কার্যকারিতাটি সম্পাদন করার জন্য, সংযোজকটির এটির কাজ করার জন্য কোনও মেমরি বেড়া প্রবর্তন করা দরকার?

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


এই সম্পর্কিত প্রশ্নে একটি আকর্ষণীয় আলোচনা আছে

জোনাথন ওয়াকেলি লিখেছেন :

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

যা সম্পর্কে ডেভিড শোয়ার্জ মন্তব্যগুলিতে জবাব দিয়েছেন :

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

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

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

কোনটি দুটি প্রশ্ন জোগায়: তাদের উভয়ই "সঠিক"? প্রকৃত বাস্তবায়ন আসলে কী করে?


9
এর বেশিরভাগ অর্থ হ'ল সংকলকটি কোনও পরিবর্তনকে কোনও রেজিস্টারে রাখা উচিত নয়। উত্স কোডে প্রতিটি অ্যাসাইনমেন্ট এবং পড়ার বাইনারি কোডে মেমরি অ্যাক্সেসের সাথে মিল থাকা উচিত।
বেসিল স্টারিনকিভিচ


4
আমি সন্দেহ করি যে বিন্দুটি হ'ল কোনও অভ্যন্তরীণ রেজিস্টারে যদি মানটি সংরক্ষণ করা হয় তবে কোনও মেমরি বেড়া কার্যকর হবে না। আমি মনে করি আপনার এখনও একই সময়ে অন্যান্য সুরক্ষা ব্যবস্থা নেওয়া দরকার।
গালিক

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

4
@ বিগত আমি এখনও একটি সংকলক দেখতে পেলাম যা volatileভেরিয়েবলের পাঠ্যগুলিকে সিপিইউ ক্যাশে অপ্টিমাইজ করা থেকে বিরত রাখে। হয় এই সমস্ত সংকলক অ-অনুগত বা মানকটি এর অর্থ এটির অর্থ নয় বলে বোঝায়। (আদর্শ কি কম্পাইলার করে এবং কি কম্পাইলার CPU- র করে তোলে মধ্যে পার্থক্য নেই এটা নির্গত কোডে কম্পাইলার কাজ যে, যখন রান মান মেনে চলে।।)
ডেভিড শোয়ার্জ

উত্তর:


58

কী volatileকরে তা ব্যাখ্যা করার পরিবর্তে , কখন আপনার ব্যবহার করা উচিত তা আমাকে ব্যাখ্যা করার অনুমতি দিন volatile

  • যখন একটি সিগন্যাল হ্যান্ডলারের ভিতরে থাকে। কারণ কোনও volatileভেরিয়েবলে লেখার বিষয়টি কেবলমাত্র সিগন্যাল হ্যান্ডলারের মধ্যে থেকে স্ট্যান্ডার্ড আপনাকে অনুমতি দেয়। যেহেতু সি ++ 11 আপনি ব্যবহার করতে পারেনstd::atomic সেই উদ্দেশ্যে তবে কেবল যদি পারমাণবিকটি লক-মুক্ত থাকে।
  • যখন সঙ্গে তার আচরণ setjmp ইন্টেল অনুযায়ী
  • হার্ডওয়ারের সাথে সরাসরি ডিল করার সময় এবং আপনি নিশ্চিত করতে চান যে সংকলকটি আপনার পড়া বা লেখার বিষয়টিকে অপ্টিমাইজ করে না।

উদাহরণ স্বরূপ:

volatile int *foo = some_memory_mapped_device;
while (*foo)
    ; // wait until *foo turns false

volatileনির্দিষ্টকরণকারী ছাড়া , সংকলক সম্পূর্ণ লুপ দূরে অপ্টিমাইজ করার অনুমতি দেওয়া হয়। দ্যvolatileসুনির্দিষ্টভাবে উল্লেখ করা কম্পাইলার এটা অনুমান করতে পারেন না যে 2 পরবর্তী লেখা যে একই মান বলে।

নোটের volatileথ্রেডগুলির সাথে কোনও সম্পর্ক নেই Note উপরের উদাহরণটিতে কোনও আলাদা থ্রেড লেখা থাকলে কাজ করে না*foo কারণ কোনও অর্পণ ক্রিয়াকলাপ জড়িত নেই।

অন্যান্য সমস্ত ক্ষেত্রে, এর ব্যবহারকে volatileবহনযোগ্য হিসাবে বিবেচনা করা উচিত এবং প্রি-সি ++ 11 সংকলক এবং সংকলক এক্সটেনশনের (যেমন এমএসভিসি এর /volatile:msস্যুইচ, যা এক্স 86 / আই 64 এর অধীনে ডিফল্টরূপে সক্ষম করা হয়েছে) ডিল করার সময় ব্যতীত আর কোড পর্যালোচনা পাস করা উচিত নয় ।


4
এটি "আরও পরবর্তী 2 টি পাঠক একই মান ফেরত" ধরে না নিতে পারে তার চেয়ে কঠোর ter এমনকি যদি আপনি কেবল একবার পড়েন এবং / অথবা মান (গুলি) ফেলে দেন তবে পঠন করতে হবে।
ফিলিপ্সি

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

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

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

4
@ ডেভিডশওয়ার্টজ কিছু সংকলক-আর্কিটেকচার জুটি প্রকৃত প্রভাবগুলি এবং কার্যকরী প্রোগ্রামগুলিতে অ্যাক্সেসের স্ট্যান্ডার্ড-নির্দিষ্ট ক্রমটিকে মানচিত্রের অভাবে অস্থিরতাগুলিতে প্রবেশ করে get এই জাতীয় কিছু জোড়ের কোনও ম্যাপিং বা তুচ্ছ অস্বাস্থ্যকর ম্যাপিং নেই তা বাস্তবায়নের মানের সাথে প্রাসঙ্গিক তবে হস্তগত বিন্দুতে নয়।
ফিলিপ্সি 18

25

সি ++ চঞ্চল কীওয়ার্ডটি কি কোনও মেমরি বেড়ের পরিচয় দেয়?

একটি সি ++ সংকলক যা স্পেসিফিকেশন অনুসারে মেমরি বেড়া প্রবর্তন করার প্রয়োজন হয় না। আপনার নির্দিষ্ট সংকলক হতে পারে; আপনার প্রশ্নটি আপনার সংকলকটির লেখকদের দিকে নির্দেশ করুন।

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

প্রকৃতপক্ষে, সি / সি ++ এ থ্রেডিংয়ের জন্য অস্থিরতা বেশ কার্যকর less এটি এড়ানোর সেরা অনুশীলন।

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

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


19
"সি / সি ++ এ অস্থিরতা অনেকটা অকেজো" " একদমই না! আপনার কাছে বিশ্বের খুব ব্যবহারকারীমোড-ডেস্কটপ-কেন্দ্রিক দৃষ্টি রয়েছে ... তবে বেশিরভাগ সি এবং সি ++ কোড এম্বেডড সিস্টেমে চলে যেখানে মেমরি-ম্যাপযুক্ত I / O এর জন্য অস্থিরতা খুব প্রয়োজন।
বেন ভয়েগট

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

4
@ বেনভয়েগ: থ্রেডিংয়ের সমস্যাগুলি কার্যকরভাবে মোকাবেলার জন্য অকেজো আমার উদ্দেশ্যযুক্ত অর্থ।
এরিক লিপার্ট

4
পছন্দ করুন তবে মেমোরি ম্যাপ করা আইও কেন volatileসি স্ট্যান্ডার্ডের সাথে প্রবর্তিত হয়েছিল। তবুও, কারণ স্ট্যান্ডার্ডটি "অ্যাক্সেস" এ আসলে কী ঘটে তার মতো জিনিসগুলি নির্দিষ্ট করতে পারে না, কারণ এটি বলে যে "অস্থায়ী-যোগ্যতাযুক্ত কোনও বস্তুর অ্যাক্সেসকে কী গঠন করে তা বাস্তবায়ন-সংজ্ঞায়িত হয়।" আজকের অনেকগুলি বাস্তবায়ন কোনও অ্যাক্সেসের একটি দরকারী সংজ্ঞা সরবরাহ করে না, যা আইএমএইচও মানের চেতনা লঙ্ঘন করে, এমনকি যদি তা চিঠির সাথে সঙ্গতিপূর্ণ হয়।
জেমস কানজে

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

13

ডেভিড যা অবহেলা করছেন তা হ'ল সি ++ স্ট্যান্ডার্ডটি কেবল নির্দিষ্ট পরিস্থিতিতে ইন্টারঅ্যাক্ট করার জন্য বেশ কয়েকটি থ্রেডের আচরণ নির্দিষ্ট করে এবং অন্য সমস্ত কিছুই অনির্ধারিত আচরণে ফলাফল দেয়। আপনি যদি পারমাণবিক ভেরিয়েবল ব্যবহার না করেন তবে কমপক্ষে একটি লেখার সাথে জড়িত এমন একটি শর্তের সংজ্ঞা নির্ধারিত।

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


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

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

আপনি কেন মনে করেন যে আমি এটি উপেক্ষা করছি? আমার যুক্তির কোন অংশটি আপনি অকার্যকর বলে মনে করেন? আমি 100% একমত যে সংকলকটি কোনও সিঙ্ক্রোনাইজেশনকে ত্যাগ করার অধিকারে পুরোপুরি।
ডেভিড শোয়ার্জ

4
এটি কেবল ভুল, বা কমপক্ষে এটি প্রয়োজনীয়টিকে উপেক্ষা করে। volatileথ্রেডের সাথে কিছু করার নেই; এর আসল উদ্দেশ্যটি ছিল মেমোরিযুক্ত আইও সমর্থন করা support এবং কমপক্ষে কিছু প্রসেসরের উপর, মেমরিযুক্ত ম্যাপযুক্ত আইও সমর্থন করে বেড়া প্রয়োজন। (সংকলকগণ এটি করেন না, তবে এটি একটি আলাদা সমস্যা))
জেমস কানজে

@ জেমস কানজির volatileথ্রেডগুলির সাথে অনেক কিছুই রয়েছে: volatileমেমরির সাথে ডিল করে যা সংকলক ছাড়াই অ্যাক্সেস করা যায় তা জেনেও এটি ব্যবহার করা যেতে পারে এবং নির্দিষ্ট সিপিইউতে থ্রেডগুলির মধ্যে ভাগ করা ডেটার ব্যবহারের অনেকগুলি আসল বিশ্ব জুড়ে রয়েছে।
কৌতূহলী

12

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

অস্থির অ্যাক্সেস বাস্তবায়নের বিষয়ে, এটি সংকলক পছন্দ।

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

আইসিসি আচরণ সম্পর্কে আমি এই উত্সটি এও বলেছি যে অস্থির মেমরি অ্যাক্সেসগুলি অর্ডার করার গ্যারান্টি দেয় না।

মাইক্রোসফ্ট ভিএস ২০১৩ সংকলকের আলাদা আচরণ রয়েছে। এই ডকুমেন্টেশনটি ব্যাখ্যা করে যে কীভাবে অস্থিরতা রিলিজ / অ্যাকোয়ার সায়েন্টিকসকে প্রয়োগ করে এবং বহু-থ্রেড অ্যাপ্লিকেশনগুলিতে লক / রিলিজে অস্থির বস্তুগুলি ব্যবহার করতে সক্ষম করে।

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

সুতরাং আমার উত্তর:

সি ++ চঞ্চল কীওয়ার্ডটি কি কোনও মেমরি বেড়ের পরিচয় দেয়?

হবে: গ্যারান্টিযুক্ত নয়, সম্ভবত না কিন্তু কিছু সংকলক এটি করতে পারে। আপনার এটি নির্ভর করে না যে এটি করে।


4
এটি অপ্টিমাইজেশন প্রতিরোধ করে না, এটি কেবল সংযোজনকারীকে নির্দিষ্ট বাধা অতিক্রম করে লোড এবং স্টোর পরিবর্তন করতে বাধা দেয়।
ডায়েটারিচ এপ্প

আপনি কী বলছেন তা পরিষ্কার নয়। আপনি কি বলছেন যে কিছু অনির্ধারিত সংকলকগুলির ক্ষেত্রে এটি ঘটেছিল যা volatileসংকলককে লোড / স্টোরগুলি পুনরায় অর্ডার করতে বাধা দেয়? বা আপনি কি বলছেন যে সি ++ স্ট্যান্ডার্ডের এটি করা দরকার? এবং যদি দ্বিতীয়টি হয় তবে আপনি কি আমার যুক্তিতে মূল প্রশ্নে উদ্ধৃত বিপরীতে সাড়া দিতে পারবেন?
ডেভিড শোয়ার্জ

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

আমি মনে করি এমএসসি সংকলকগুলির কয়েকটি সংস্করণ বেড়া শব্দার্থক প্রয়োগ করেছে volatile, তবে ভিজ্যুয়াল স্টুডিওজ ২০১২
জেমস কানজে

@ জামেসকানজে যার মূলত অর্থ হ'ল এর একমাত্র বহনযোগ্য আচরণ volatileহ'ল বিশেষত মান দ্বারা অঙ্কিত । ( setjmp, সিগন্যাল, এবং আরও।)
ডেভিড শোয়ার্জ

7

সংকলকটি কেবল যতদূর জানি ইটানিয়াম আর্কিটেকচারে একটি মেমরি বেড়া সন্নিবেশ করিয়েছে।

volatileশব্দ সত্যিই সেরা অ্যাসিঙ্ক্রোনাস পরিবর্তন, যেমন, সংকেত হ্যান্ডলার এবং মেমরি ম্যাপ রেজিস্টার ব্যবহার করা হয়; মাল্টিথ্রেডেড প্রোগ্রামিংয়ের জন্য এটি সাধারণত ভুল সরঞ্জাম।


4
প্রকার, রকম. 'সংকলক' (এমএসভিসি) যখন এআরএম ব্যতীত অন্য কোনও আর্কিটেকচার লক্ষ্যবস্তু হয় এবং / অস্থির: এমএস সুইচ ব্যবহৃত হয় (ডিফল্ট) an এমএসডিএন.মাইক্রোসফটকম /en-us/library/12a04hfd.aspx দেখুন । অন্যান্য সংকলক আমার জ্ঞানের উদ্বায়ী ভেরিয়েবলগুলিতে বেড়া inোকান না। সরাসরি হার্ডওয়্যার, সিগন্যাল হ্যান্ডলার বা নন-সি ++ 11 অনুসারে সংযোজকগুলির সাথে ডিল না করেই অস্থির ব্যবহার এড়ানো উচিত।
স্টেফান

@ স্টেফান নং volatileএমন অনেকগুলি ব্যবহারের জন্য চূড়ান্ত কার্যকর যেগুলি কখনও হার্ডওয়ারের সাথে মোকাবিলা করে না। আপনি যখনই সিগি / সি ++ কোডটি নিবিড়ভাবে অনুসরণ করেন এমন সিপিইউ কোড তৈরি করতে বাস্তবায়নটি চান তখনই ব্যবহার করুন volatile
কৌতূহলী

7

এটি "সংকলক" কোন সংকলক তার উপর নির্ভর করে। ভিজ্যুয়াল সি ++ ২০০৫ সাল থেকে does


ভিসি ++, 2012 একটি বেড়া সন্নিবেশ বলে মনে হচ্ছে না: int volatile i; int main() { return i; }ঠিক দুই নির্দেশাবলী সহ একটি প্রধান উত্পন্ন: mov eax, i; ret 0;
জেমস কানজে

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

cl /helpসংস্করণটি 18.00.21005.1 বলে। এটি ডিরেক্টরিতে রয়েছে C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC। কমান্ড উইন্ডোতে শিরোলেখটি ভিএস 2013 বলেছে So সুতরাং সংস্করণটির প্রতি শ্রদ্ধা জানাতে ... আমি কেবলমাত্র বিকল্পগুলিই ব্যবহার করেছি /c /O2 /Fa। (এটি ছাড়া এটি /O2স্থানীয় স্ট্যাক ফ্রেমও স্থাপন করে। তবে এখনও কোনও বেড়ার নির্দেশ নেই))
জেমস কানজে

@ জামেসকানজি: আমি আর্কিটেকচারে আরও আগ্রহী ছিলাম, যেমন "মাইক্রোসফ্ট (আর) সি / সি ++ এক্স 64৪ এর জন্য 18.00.30723 অনুকূলিতকরণ সংকলক সংস্করণ" সম্ভবত কোনও বেড়া নেই কারণ x86 এবং x64 এর মেমরির মডেলটিতে মোটামুটি শক্তিশালী ক্যাশে সহবাসের গ্যারান্টি রয়েছে যার সাথে শুরু হয় ?
বেন ভয়েগট

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

5

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

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

তর্কযুক্তভাবে (এবং এটি একটি আর্গুমেন্ট আমি গ্রহণ করি), এটি স্ট্যান্ডার্ডের উদ্দেশ্যটিকে লঙ্ঘন করে, যেহেতু হার্ডওয়্যার ঠিকানাগুলি মেমরিযুক্ত ম্যাপযুক্ত আইও হিসাবে স্বীকৃতি দেয় না এবং কোনও পুনরায় ক্রমবর্ধমান ইত্যাদি বাধা দেয় না, আপনি মেমরি ম্যাপযুক্ত আইওর জন্যও অস্থির ব্যবহার করতে পারবেন না, কমপক্ষে স্পার্ক বা ইন্টেল আর্কিটেকচারে। কখনই কম নয়, আমি দেখেছি (কম সোনার সিসি, জি ++ এবং এমএসসি) এরকম কোনও কলার কোনও বেড়া বা মেম্বারের নির্দেশনা দেয় না। (মাইক্রোসফ্ট বিধিগুলি বাড়ানোর প্রস্তাব দেওয়ার সময় সম্পর্কে volatile, আমি মনে করি তাদের কিছু সংকলক তাদের প্রস্তাব বাস্তবায়িত করেছিল এবং অস্থির অ্যাক্সেসের জন্য বেড়া নির্দেশগুলি প্রেরণ করে recent সাম্প্রতিক সংকলকগুলি কী করে তা যাচাই করিনি, তবে এটি যদি নির্ভর করে তবে অবাক হবেন না কিছু সংকলক বিকল্পে I আমি যে সংস্করণটি চেক করেছি — আমি মনে করি এটি VS6.0 was তবে বেড়া নির্গত হয়নি))


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

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

4
@ ডেভিডশওয়ার্টজ: পেরিফেরিয়ালগুলিতে এক্সক্লুসিভ (বা মিটেক্স'ড) মেমরি-ম্যাপযুক্ত I / O এর জন্য volatileশব্দার্থবিজ্ঞান পুরোপুরি পর্যাপ্ত। সাধারণত এ জাতীয় পেরিফেরালগুলি তাদের মেমরি অঞ্চলগুলিকে নন-ক্যাশেযোগ্য হিসাবে প্রতিবেদন করে, যা হার্ডওয়্যার স্তরে পুনর্বিন্যাসে সহায়তা করে।
বেন ভয়েগট

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

@ জামেসকানজি: আমি যা কিছুটা অনুসন্ধান করেছি তা থেকে মনে হচ্ছে স্পার্কের কাছে স্মরণশক্তিটির "বিকল্প মতামত" এর জন্য ঠিকানা বিস্তৃত রয়েছে যা অপ্রকাশ্য নয় dedicated যতক্ষণ আপনার অস্থির অ্যাক্সেস ASI_REAL_IOঠিকানার জায়গার অংশে নির্দেশ করে ততক্ষণ আমার মনে হয় আপনার ভাল হওয়া উচিত। (আল্টেরা এনআইওএস একই ধরণের কৌশল ব্যবহার করে, ঠিকানার উচ্চ বিট এমএমইউ বাইপাস নিয়ন্ত্রণ করে; আমি নিশ্চিত যে অন্যরাও রয়েছেন)
বেন ভয়েগট

5

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

স্মৃতি বাধা সম্পর্কিত একটি বিট ব্যাখ্যা। একটি সাধারণ সিপিইউতে বিভিন্ন স্তরের মেমরি অ্যাক্সেস থাকে। এখানে একটি মেমরি পাইপলাইন, বিভিন্ন স্তরের ক্যাশে, তারপরে র‌্যাম ইত্যাদি রয়েছে

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

ক্যাশে (গুলি) সাধারণত সিপিইউগুলির মধ্যে স্বয়ংক্রিয়ভাবে সুসংগত থাকে। যদি কেউ নিশ্চিত করতে চান যে ক্যাশেটি র‌্যামের সাথে সিঙ্কে রয়েছে তবে ক্যাশে ফ্লাশ প্রয়োজন। এটি একটি মেমবারের থেকে খুব আলাদা।


4
সুতরাং আপনি বলছেন যে সি ++ স্ট্যান্ডার্ড বলছে যে volatileকেবল সংকলক অপ্টিমাইজেশন অক্ষম করে? এটা কোন মানে না। সংকলক যে কোনও অপ্টিমাইজেশন করতে পারে, কমপক্ষে নীতিগতভাবে, সমানভাবে সিপিইউ দ্বারা সম্পন্ন করতে পারে। সুতরাং যদি স্ট্যান্ডার্ডটি বলে যে এটি কেবল সংকলক অপ্টিমাইজেশানগুলি অক্ষম করে, এর অর্থ এটি পোর্টেবল কোডের উপর নির্ভর করতে পারে এমন কোনও আচরণ প্রদান করবে না। তবে এটি স্পষ্টতই সত্য নয় কারণ পোর্টেবল কোড তার আচরণের উপর নির্ভর করতে পারেsetjmp সম্মতি এবং সংকেতগুলির পারে।
ডেভিড শোয়ার্জ

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

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

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

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

4

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

নোট করুন যে কয়েকটি সংকলক volatileএই প্ল্যাটফর্মগুলিতে আরও শক্তিশালী বা দরকারী করার জন্য সি ++ স্ট্যান্ডার্ডের প্রয়োজনের বাইরে চলে গেছে । পোর্টেবল কোড নির্ভর করা উচিত নয়volatile সি ++ স্ট্যান্ডার্ডে নির্দিষ্ট করা ছাড়াও কিছু জন্য ।


2

আমি সবসময় বিঘ্নিত পরিষেবার রুটিনগুলিতে অস্থিরতা ব্যবহার করি, যেমন আইএসআর (প্রায়শই সমাবেশ কোড) কিছু মেমরি অবস্থান পরিবর্তন করে এবং বিঘ্নিত প্রসঙ্গের বাইরে চলমান উচ্চ স্তরের কোডটি অস্থির দিকে পয়েন্টারের মাধ্যমে মেমরির অবস্থান অ্যাক্সেস করে।

আমি র‌্যামের পাশাপাশি মেমরি-ম্যাপযুক্ত আইওর জন্য এটি করি।

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

যেহেতু আমরা "সিস্টেমে" আরও স্টাফগুলি গাদা করি যা অবজেক্ট কোডটি কার্যকর করে প্রায় সমস্ত বেট বন্ধ রয়েছে, কমপক্ষে আমি এই আলোচনাটি পড়ি read কোনও সংকলক কীভাবে সব ঘাঁটিটি কভার করতে পারে?


0

আমি মনে করি যে অস্থির এবং নির্দেশ পুনঃক্রমের চারপাশে বিভ্রান্তি সিপিইউগুলির পুনঃক্রমগুলির 2 টি ধারণা থেকে উদ্ভূত:

  1. আদেশ ছাড়াই কার্যকর।
  2. অন্যান্য সিপিইউগুলির দ্বারা দেখা মেমরির সিকোয়েন্স / রচনাগুলি (প্রতিটি সিপিইউ একটি পৃথক ক্রম দেখতে পারে এমন অর্থে পুনরায় অর্ডার করে)।

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

আদেশ ছাড়াই কার্যকর

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

অন্যান্য সিপিইউ দ্বারা দেখা মেমরির পাঠ্য / লেখার ক্রম

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

সূত্র:


0

আমি যখন 3D ও গ্রাফিক্স এবং গেম ইঞ্জিন বিকাশের জন্য একটি অনলাইন ডাউনলোডযোগ্য ভিডিও টিউটোরিয়াল দিয়েছি তখন আধুনিক ওপেনএল-এর সাথে কাজ করছি। আমরা volatileআমাদের ক্লাসগুলির মধ্যে একটিতে ব্যবহার করেছি । টিউটোরিয়াল ওয়েবসাইটটি এখানে পাওয়া যাবে এবং volatileকীওয়ার্ডের সাথে কাজ করা Shader Engineভিডিওটি 98 নম্বর সিরিজের ভিডিওতে পাওয়া যাবে These এই কাজগুলি আমার নিজের নয় তবে অনুমোদিত হয়েছে Marek A. Krzeminski, MAScএবং এটি ভিডিও ডাউনলোড পৃষ্ঠার একটি অংশ।

"যেহেতু আমরা এখন আমাদের গেমগুলি একাধিক থ্রেডে চালাতে পারি তা থ্রেডগুলির মধ্যে ডেটা সঠিকভাবে সিঙ্ক্রোনাইজ করা জরুরী video

আপনি যদি তার ওয়েবসাইটে সাবস্ক্রাইব হন এবং এই ভিডিওর মধ্যে তার ভিডিওর অ্যাক্সেস রয়েছে তবে তিনি এই ব্যবহারটি সম্পর্কিত এই নিবন্ধটি উল্লেখ Volatileকরেছেনmultithreading প্রোগ্রামিং।

উপরের লিঙ্কটি থেকে এখানে নিবন্ধটি দেওয়া হয়েছে: http://www.drdobbs.com/cpp/volatile-the-multithreaded-programmers-b/184403766

উদ্বায়ী: মাল্টিথ্রেডেড প্রোগ্রামার সেরা বন্ধু

আন্দ্রেই আলেকজান্দ্রেস্কু, ফেব্রুয়ারি 01, 2001 By

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

আমি আপনার মেজাজ নষ্ট করতে চাই না, তবে এই কলামটি বহুবিধ প্রোগ্রামিংয়ের ভয়ঙ্কর বিষয়টিকে সম্বোধন করে। যদি - জেনেরিকের পূর্বের কিস্তি হিসাবে বলা হয় - ব্যতিক্রম-নিরাপদ প্রোগ্রামিং কঠিন, এটি বহুবিধ প্রোগ্রামিংয়ের তুলনায় বাচ্চার খেলা।

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

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

শুধু একটি ছোট কীওয়ার্ড

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

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

নিম্নলিখিত কোড বিবেচনা করুন:

class Gadget {
public:
    void Wait() {
        while (!flag_) {
            Sleep(1000); // sleeps for 1000 milliseconds
        }
    }
    void Wakeup() {
        flag_ = true;
    }
    ...
private:
    bool flag_;
};

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

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

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

class Gadget {
public:
    ... as above ...
private:
    volatile bool flag_;
};

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

ব্যবহারকারী-সংজ্ঞায়িত প্রকারের সাথে অস্থির ব্যবহার

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

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

আসুন উদাহরণস্বরূপ ব্যবহারকারী-সংজ্ঞায়িত প্রকারগুলিতে কীভাবে অস্থিরতা কাজ করে তা বর্ণনা করি।

class Gadget {
public:
    void Foo() volatile;
    void Bar();
    ...
private:
    String name_;
    int state_;
};
...
Gadget regularGadget;
volatile Gadget volatileGadget;

আপনি যদি মনে করেন যে অস্থির জিনিসগুলি দিয়ে এটি কার্যকর নয় তবে কিছু অবাক হওয়ার জন্য প্রস্তুত করুন।

volatileGadget.Foo(); // ok, volatile fun called for
                  // volatile object
regularGadget.Foo();  // ok, volatile fun called for
                  // non-volatile object
volatileGadget.Bar(); // error! Non-volatile function called for
                  // volatile object!

একটি অ-যোগ্যতাসম্পন্ন টাইপ থেকে এর অস্থির প্রতিরূপে রূপান্তর তুচ্ছ। তবে কনস্টের মতোই, আপনি ট্রিপটি অস্থির থেকে অ-যোগ্যতাসম্পন্নের দিকে ফেরাতে পারবেন না। আপনার অবশ্যই একটি castালাই ব্যবহার করা উচিত:

Gadget& ref = const_cast<Gadget&>(volatileGadget);
ref.Bar(); // ok

একটি অস্থির-যোগ্য শ্রেণি কেবল তার ইন্টারফেসের একটি উপসেটটিতে অ্যাক্সেস দেয়, একটি উপসেট যা শ্রেণি প্রয়োগকারীটির নিয়ন্ত্রণে থাকে। ব্যবহারকারীরা কেবল কনস্টাস্ট্রাস্ট ব্যবহার করে এই ধরণের ইন্টারফেসে সম্পূর্ণ অ্যাক্সেস পেতে পারেন। তদতিরিক্ত, স্থিরতার মতো, অস্থিরতা শ্রেণি থেকে তার সদস্যদের কাছে প্রচার করে (উদাহরণস্বরূপ, ভোল্টাইলগ্যাজেট.নাম_ এবং ভোল্টাইলগ্যাজেট.স্টেট_টি অস্থির পরিবর্তনশীল)।

অস্থির, সমালোচনা বিভাগ এবং রেস শর্তসমূহ

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

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

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

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

সংক্ষেপে, থ্রেডগুলির মধ্যে ভাগ করা ডেটা একটি সমালোচনামূলক বিভাগের বাইরে ধারণাগতভাবে অস্থির এবং সমালোচনামূলক বিভাগের অভ্যন্তরে অ-উদ্বায়ী is

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

লকিংপি.টি.

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

প্রথমে আসুন একটি ক্লাস মিটেক্সের কঙ্কালটি সংজ্ঞায়িত করুন যার সাহায্যে লকিংপিআরটি কাজ করবে:

class Mutex {
public:
    void Acquire();
    void Release();
    ...    
};

লকিংপিআরটি ব্যবহার করতে, আপনি আপনার অপারেটিং সিস্টেমের নেটিভ ডেটা স্ট্রাকচার এবং আদিম ফাংশনগুলি ব্যবহার করে Mutex প্রয়োগ করেন।

লকিংপিআরটি নিয়ন্ত্রিত ভেরিয়েবলের প্রকারের সাথে সঞ্চারিত হয়। উদাহরণস্বরূপ, আপনি যদি একটি উইজেটটি নিয়ন্ত্রণ করতে চান তবে আপনি একটি লকিংপিআরটি ব্যবহার করেন যা আপনি ভোল্টাইল উইজেটের টাইপের একটি চলক দিয়ে আরম্ভ করেন।

লকিংপিআরটির সংজ্ঞাটি খুব সহজ। লকিংপিআরটি একটি অপ্রয়োজনীয় স্মার্ট পয়েন্টার প্রয়োগ করে। এটি সম্পূর্ণরূপে কনস্ট_কাস্ট এবং সমালোচনামূলক বিভাগ সংগ্রহের দিকে মনোনিবেশ করে।

template <typename T>
class LockingPtr {
public:
    // Constructors/destructors
    LockingPtr(volatile T& obj, Mutex& mtx)
      : pObj_(const_cast<T*>(&obj)), pMtx_(&mtx) {    
        mtx.Lock();    
    }
    ~LockingPtr() {    
        pMtx_->Unlock();    
    }
    // Pointer behavior
    T& operator*() {    
        return *pObj_;    
    }
    T* operator->() {   
        return pObj_;   
    }
private:
    T* pObj_;
    Mutex* pMtx_;
    LockingPtr(const LockingPtr&);
    LockingPtr& operator=(const LockingPtr&);
};

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

বলুন আপনার কাছে দুটি থ্রেড রয়েছে যা ভেক্টর অবজেক্টটি ভাগ করে:

class SyncBuf {
public:
    void Thread1();
    void Thread2();
private:
    typedef vector<char> BufT;
    volatile BufT buffer_;
    Mutex mtx_; // controls access to buffer_
};

একটি থ্রেড ফাংশনের অভ্যন্তরে, আপনি বাফার_ সদস্য ভেরিয়েবলের নিয়ন্ত্রিত অ্যাক্সেস পেতে কেবল একটি লকিংপিআরটি ব্যবহার করেন:

void SyncBuf::Thread1() {
    LockingPtr<BufT> lpBuf(buffer_, mtx_);
    BufT::iterator i = lpBuf->begin();
    for (; i != lpBuf->end(); ++i) {
        ... use *i ...
    }
}

কোডটি লিখতে এবং বুঝতে খুব সহজ - যখনই আপনাকে বাফার_ ব্যবহার করতে হবে, আপনাকে অবশ্যই এটির দিকে নির্দেশ করে একটি লকিংপিআরটি তৈরি করতে হবে। একবার আপনি এটি করার পরে, আপনি ভেক্টরের পুরো ইন্টারফেসে অ্যাক্সেস পাবেন।

সুন্দর অংশটি হ'ল আপনি যদি কোনও ভুল করেন তবে সংকলকটি এটি উল্লেখ করবে:

void SyncBuf::Thread2() {
    // Error! Cannot access 'begin' for a volatile object
    BufT::iterator i = buffer_.begin();
    // Error! Cannot access 'end' for a volatile object
    for ( ; i != lpBuf->end(); ++i ) {
        ... use *i ...
    }
}

আপনি বাফার_এর কোনও ক্রিয়াকলাপ অ্যাক্সেস করতে পারবেন না যতক্ষণ না আপনি কনস্টাকাস্ট প্রয়োগ করেন বা লকিংপিটিআর ব্যবহার না করেন। পার্থক্যটি হ'ল লকিংপিআরটি কনস্টাস্টকস্টটিকে অস্থায়ী ভেরিয়েবলগুলিতে প্রয়োগ করার একটি অর্ডারযুক্ত উপায় সরবরাহ করে।

লকিংপিআরটি উল্লেখযোগ্যভাবে উদ্ভুত। আপনার যদি কেবল একটি ফাংশন কল করতে হয় তবে আপনি একটি নামবিহীন অস্থায়ী লকিংপিআরটি অবজেক্ট তৈরি করতে পারেন এবং এটি সরাসরি ব্যবহার করতে পারেন:

unsigned int SyncBuf::Size() {
return LockingPtr<BufT>(buffer_, mtx_)->size();
}

আদিম প্রকারগুলিতে ফিরে যান

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

আসুন একটি উদাহরণ বিবেচনা করুন যেখানে একাধিক থ্রেডগুলি টাইপ ইন্টের একটি পরিবর্তনশীল ভাগ করে।

class Counter {
public:
    ...
    void Increment() { ++ctr_; }
    void Decrement() { —ctr_; }
private:
    int ctr_;
};

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

  • একটি রেজিস্টার যে পরিবর্তনশীল পড়তে
  • রেজিস্টারে মান বৃদ্ধি করে
  • ফলাফলটি স্মৃতিতে ফিরে আসে

এই তিন-পদক্ষেপের অপারেশনটিকে আরএমডাব্লু (রিড-মডিফাই-রাইটিং) বলা হয়। আরএমডাব্লু অপারেশনের অংশ পরিবর্তিত করার সময়, অন্যান্য প্রসেসরের মেমরিতে অ্যাক্সেস দেওয়ার জন্য বেশিরভাগ প্রসেসর মেমরি বাসটি মুক্ত করে।

যদি সেই সময় অন্য প্রসেসর একই ভেরিয়েবলের উপর আরএমডাব্লু অপারেশন করে তবে আমাদের একটি রেসের শর্ত রয়েছে: দ্বিতীয় রাইটটি প্রথমটির প্রভাবকে ওভাররাইট করে।

এড়াতে, আপনি আবার লকিংপিটিআরের উপর নির্ভর করতে পারেন:

class Counter {
public:
    ...
    void Increment() { ++*LockingPtr<int>(ctr_, mtx_); }
    void Decrement() { —*LockingPtr<int>(ctr_, mtx_); }
private:
    volatile int ctr_;
    Mutex mtx_;
};

এখন কোডটি সঠিক, তবে সিঙ্কবুফের কোডের সাথে তুলনা করার সময় এর মানটি নিম্নমানের। কেন? কাউন্টার সহ, আপনি ভুলভাবে সিটিআর_কে সরাসরি (লক না করে) অ্যাক্সেস করলে সংকলক আপনাকে সতর্ক করবে না। সংকলক সিটিটি_টি অস্থির হলে ++ সিটিআর_ সংকলন করে, যদিও উত্পন্ন কোডটি কেবল ভুল incor সংকলকটি আর আপনার মিত্র নয়, এবং কেবলমাত্র আপনার মনোযোগ আপনাকে জাতিদের অবস্থা এড়াতে সহায়তা করতে পারে।

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

অস্থায়ী সদস্য ফাংশন

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

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

উদাহরণস্বরূপ, আপনি একটি শ্রেণি উইজেট সংজ্ঞায়িত করেছেন যা দুটি বৈকল্পিকতে একটি ক্রিয়াকলাপ প্রয়োগ করে - একটি থ্রেড-নিরাপদ এবং একটি দ্রুত, অরক্ষিত।

class Widget {
public:
    void Operation() volatile;
    void Operation();
    ...
private:
    Mutex mtx_;
};

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

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

void Widget::Operation() volatile {
    LockingPtr<Widget> lpThis(*this, mtx_);
    lpThis->Operation(); // invokes the non-volatile function
}

সারসংক্ষেপ

মাল্টিথ্রেডেড প্রোগ্রামগুলি লেখার সময় আপনি আপনার সুবিধার জন্য উদ্বায়ী ব্যবহার করতে পারেন। আপনাকে অবশ্যই নিম্নলিখিত বিধিগুলিকে আঁকড়ে থাকতে হবে:

  • সমস্ত ভাগ করা অবজেক্টগুলি অস্থির হিসাবে সংজ্ঞায়িত করুন।
  • আদিম ধরণের সাথে সরাসরি অস্থির ব্যবহার করবেন না।
  • ভাগ করা ক্লাস সংজ্ঞায়িত করার সময়, থ্রেড সুরক্ষা প্রকাশ করতে অস্থায়ী সদস্য ফাংশন ব্যবহার করুন।

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

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

স্বীকৃতি

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


আন্দ্রে আলেকজান্দ্রেস্কু সিয়াটল, ডাব্লিউএ-তে ভিত্তিক রিয়েল নেটওয়ার্কস ইনক (www.realnetworks.com) এর ডেভলপমেন্ট ম্যানেজার এবং প্রশংসিত বই মডার্ন সি ++ ডিজাইনের লেখক। Www.moderncppdesign.com এ তার সাথে যোগাযোগ করা যেতে পারে। আন্দ্রেই সি ++ সেমিনার (www.gotw.ca/cpp_seminar) এর অন্যতম বৈশিষ্ট্যযুক্ত প্রশিক্ষকও।

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


0

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

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

volatile int i;
i = 1;
int j = i; 
if (j == 1) // not assumed to be true

volatile"সি একটি উচ্চ স্তরের সমাবেশ ভাষা" টুলবাক্সের মধ্যে সবচেয়ে গুরুত্বপূর্ণ সরঞ্জাম হতে পারে ।

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

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

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