প্রোগ্রামার স্তরে সি ++ এসটিডি :: পরমাণু দিয়ে কীসের নিশ্চয়তা পাওয়া যায়?


9

আমি বেশ কয়েকটি নিবন্ধ, আলোচনা এবং স্ট্যাকওভারফ্লো প্রশ্নগুলি শুনেছি এবং পড়েছি std::atomicএবং আমি নিশ্চিত হতে চাই যে আমি এটি ভালভাবে বুঝতে পেরেছি। কারণ আমি এখনও ক্যাশে লাইন নিয়ে কিছুটা বিভ্রান্ত হয়ে পড়েছি এমইএসআইতে সম্ভাব্য বিলম্বের কারণে (বা উত্পন্ন) ক্যাশে সংহতি প্রোটোকল, স্টোর বাফারস, সারিগুলি অবৈধ করে রাখা ইত্যাদি।

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

[টি 1: থ্রেড 1 টি 2: থ্রেড 2 ভি 1: শেয়ার করা পারমাণবিক পরিবর্তনশীল]

আমি বুঝতে পেরেছি যে std :: পারমাণবিক গ্যারান্টি দেয় যে,

(1) কোনও ভেরিয়েবলে কোনও ডেটা রেস হয় না (ক্যাশে লাইনে একচেটিয়া অ্যাক্সেসের জন্য ধন্যবাদ)।

(২) আমরা কোন মেমরি_অর্ডার ব্যবহার করি তার উপর নির্ভর করে এটি (বাধা সহ) গ্যারান্টি দেয় যে ক্রমিক ধারাবাহিকতা ঘটে (বাধার আগে, একটি বাধা বা উভয়ের পরে)।

(3) টি 1 এ পারমাণবিক লেখার (ভি 1) পরে, টি 2-তে একটি পারমাণবিক আরএমডাব্লু (ভি 1) সুসংগত হবে (এর ক্যাশে লাইন টি 1-তে লিখিত মান সহ আপডেট করা হবে)।

তবে ক্যাশে সংহতি প্রাইমারের উল্লেখ হিসাবে,

এই সমস্ত কিছুর অর্থ এই যে, ডিফল্টরূপে, লোডগুলি বাসি ডেটা আনতে পারে (যদি কোনও সম্পর্কিত অবৈধকরণের অনুরোধটি অবৈধতার সারিতে বসে থাকে)

সুতরাং, নিম্নলিখিতটি কি সঠিক?

(৪) std::atomicটি গ্যারান্টি দেয় না যে টি 2 টি টি-তে একটি পারমাণবিক লেখার (ভি) পরে পরমাণু পাঠ (ভি) -র 'বাসি' মান পড়বে না।

প্রশ্নগুলি যদি (4) সঠিক হয়: টি 1-তে পারমাণবিক লিখন যদি দেরি না করেই ক্যাশে লাইনটিকে অকার্যকর করে দেয় তবে কেন পারমাণবিক আরএমডাব্লু অপারেশন করলে পারমাণবিক পাঠ না করে T2 অবৈধকরণ কার্যকর হওয়ার অপেক্ষায় থাকে?

(4) ভুল হলে প্রশ্নগুলি: কখন একটি থ্রেড একটি 'বাসি' মান এবং কার্যকর করতে "এটি দৃশ্যমান" পড়তে পারে, তাহলে?

আমি আপনার উত্তর অনেক প্রশংসা করি

আপডেট 1

সুতরাং মনে হয় আমি তখন ভুল ছিলাম (3)। প্রাথমিক ভি 1 = 0 এর জন্য নিম্নলিখিত ইন্টারলিওভটি কল্পনা করুন:

T1: W(1)
T2:      R(0) M(++) W(1)

যদিও এই ক্ষেত্রে টি 2 এর আরএমডাব্লু সম্পূর্ণরূপে ডাব্লু (1) এর পরে ঘটবে তার গ্যারান্টিযুক্ত, এটি এখনও একটি 'বাসি' মান (আমার ভুল ছিল) পড়তে পারে। এর মতে, পারমাণবিক সম্পূর্ণ ক্যাশে একাত্মতার গ্যারান্টি দেয় না, কেবল ক্রমযুক্ত ধারাবাহিকতা।

আপডেট 2

(5) এখন এই উদাহরণটি কল্পনা করুন (x = y = 0 এবং এটি পারমাণবিক):

T1: x = 1;
T2: y = 1;
T3: if (x==1 && y==0) print("msg");

আমরা যে কথা বলেছি তার অনুসারে, স্ক্রিনে প্রদর্শিত "msg" দেখে আমাদের টি -২ এর পরে এক্স 2 কার্যকর করা হয়েছিল তার বাইরে তথ্য দেয় না। সুতরাং নিম্নলিখিত দুটি মৃত্যুদণ্ড কার্যকর হতে পারে:

  • টি 1 <টি 3 <টি 2
  • টি 1 <টি 2 <টি 3 (যেখানে টি 3 এক্স = 1 দেখেছে তবে এখনও y = 1 নয়)

এটা কি সঠিক?

()) যদি কোনও থ্রেড সর্বদা 'বাসি' মানগুলি পড়তে পারে, তবে আমরা সাধারণত "প্রকাশিত" দৃশ্যাবলীটি গ্রহণ করি তবে কিছু ডেটা প্রস্তুত রয়েছে এমন সিগন্যালের পরিবর্তে, আমরা ঠিক এর বিপরীতে করি (ডেটা মুছুন)?

T1: delete gameObjectPtr; is_enabled.store(false, std::memory_order_release);
T2: while (is_enabled.load(std::memory_order_acquire)) gameObjectPtr->doSomething();

যেখানে টি -2 টি এখনও মুছে ফেলা পিটিআর ব্যবহার করবে যতক্ষণ না দেখা যাচ্ছে যে_স্কৃত হয়েছে তা মিথ্যা।

()) এছাড়াও, থ্রেডগুলি 'বাসি' মানগুলি পড়তে পারে তার অর্থ একটি মুটেক্স কেবলমাত্র একটি লক-মুক্ত পরমাণু অধিকার দিয়ে প্রয়োগ করা যায় না? এটির জন্য থ্রেডগুলির মধ্যে একটি সমন্বয় ব্যবস্থা দরকার। এটির জন্য কী লকযোগ্য পারমাণবিক প্রয়োজন?

উত্তর:


3
  1. হ্যাঁ, কোনও ডেটা রেস নেই
  2. হ্যাঁ, উপযুক্ত memory_orderমানগুলির সাথে আপনি ক্রমান্বয়ে ধারাবাহিকতার গ্যারান্টি দিতে পারেন
  3. একটি পারমাণবিক পঠন-পরিবর্তন-লিখন সর্বদা সম্পূর্ণরূপে সম্পূর্ণরূপে আগে বা সম্পূর্ণ একই ভেরিয়েবলে পরমাণু লেখার পরে ঘটবে occur
  4. হ্যাঁ, টি 2 টি -২০ তে পারমাণবিক লেখার পরে চলক থেকে একটি বাসি মান পড়তে পারে

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

টপিক সবসময় মামুলি মান পড়তে পারেন, যখন ঘটে-পূর্বে গ্যারান্টী ছাড়া আপেক্ষিক ক্রম

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

উদাহরণস্বরূপ আপডেট করুন

যদি টি 1 লিখতে থাকে x=1এবং টি 2 প্রাথমিকভাবে 0 x++দিয়ে xথাকে তবে স্টোরেজের দৃষ্টিকোণ থেকে পছন্দগুলি হ'ল x:

  1. টি 1 এর x=1লেখাটি প্রথমে, তাই টি 1 লিখেন , তারপরে টি 2 পড়েন x==1, বৃদ্ধি হয় যা 2 হয় এবং x=2একক পরমাণু অপারেশন হিসাবে ফিরে আসে back

  2. টি-এর লেখা দ্বিতীয়। টি 2 পড়ে x==0, এটি 1 এ বৃদ্ধি করে এবং x=1একক ক্রিয়াকলাপ হিসাবে ফিরে আসে , তখন টি 1 লিখেছেন x=1

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

এইভাবে টি 1 জারি করতে পারে x=1, তারপরে অন্যান্য জিনিসগুলি নিয়ে এগিয়ে চলুন, যদিও টি 2 এখনও পড়বে x==0(এবং এভাবে লিখবে x=1)।

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

আরএমডাব্লু অপারেশন থেকে পড়া মানটিতে শর্তযুক্ত থাকলে এটি সর্বাধিক স্পষ্ট।

আপডেট 2

  1. আপনি যদি memory_order_seq_cstসমস্ত পারমাণবিক ক্রিয়াকলাপের জন্য (ডিফল্ট) ব্যবহার করেন তবে আপনাকে এই ধরণের জিনিস সম্পর্কে চিন্তা করার দরকার নেই। প্রোগ্রামের দৃষ্টিকোণ থেকে, আপনি যদি "msg" দেখতে পান তবে টি 1 দৌড়ে, তারপরে টি 3, তারপরে টি 2।

আপনি যদি অন্য মেমোরি ক্রমগুলি (বিশেষত memory_order_relaxed) ব্যবহার করেন তবে আপনি আপনার কোডে অন্যান্য পরিস্থিতি দেখতে পাবেন।

  1. এই ক্ষেত্রে, আপনার একটি বাগ রয়েছে। ধরুন is_enabledপতাকাটি সত্য, যখন টি 2 এর whileলুপটি প্রবেশ করবে , তাই এটি শরীর চালানোর সিদ্ধান্ত নেয়। টি 1 এখন ডেটা মুছে ফেলে, এবং টি 2 তারপরে পয়েন্টারটিকে ডিফারেন্স করে, যা একটি ঝুঁকির পয়েন্টার এবং অপরিবর্তিত আচরণ অনুসরণ করে । পরমাণুগুলি পতাকাটিতে ডেটা রেস প্রতিরোধের বাইরে কোনওভাবে সহায়তা বা বাধা দেয় না।

  2. আপনি একটি একক পরমাণু ভেরিয়েবল সহ একটি মিটেক্স প্রয়োগ করতে পারেন


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

সুতরাং যদি "থ্রেডগুলি সর্বদা বাসি মানগুলি পড়তে পারে" এর অর্থ হ'ল ক্যাশে সুসংহততা কখনই গ্যারান্টিযুক্ত হয় না (কমপক্ষে সি ++ প্রোগ্রামার স্তরে)। আপনি আমার আপডেট 2 একবার তাকান করতে পারেন দয়া করে?
অ্যালবার্ট ক্যাল্ডাস

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

1

(3) সম্পর্কিত - এটি ব্যবহৃত মেমরির ক্রমের উপর নির্ভর করে। যদি উভয়ই দোকান এবং আরএমডাব্লু অপারেশন ব্যবহার করে std::memory_order_seq_cst, তবে উভয় ক্রিয়াকলাপ কোনও উপায়ে অর্ডার করা হয় - অর্থাত্ স্টোরটি আরএমডাব্লু এর আগে ঘটে থাকে, বা অন্যভাবে রাউন্ডে হয়। যদি স্টোরটি আরএমডাব্লু এর আগে অর্ডার হয় তবে গ্যারান্টি দেওয়া হয় যে আরএমডাব্লু অপারেশনটি স্টোর করা মানটি "দেখায়"। যদি স্টোরটি আরএমডাব্লুয়ের পরে অর্ডার করা হয় তবে এটি আরএমডাব্লু অপারেশন দ্বারা লিখিত মানটি ওভাররাইট করে।

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

আপনি যদি আর একটি নিবন্ধ পড়তে চান তবে আমি আপনাকে সি / সি ++ প্রোগ্রামারগুলির জন্য মেমরি মডেলগুলিতে উল্লেখ করতে পারি ।


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

1
শুনে খুশি হলাম - এই নিবন্ধটি আমার মাস্টারের থিসিস থেকে কিছুটা বর্ধিত এবং সংশোধিত অধ্যায়। :-) এটি সি ++ 11 হিসাবে পরিচিত হিসাবে মেমরির মডেলটিতে ফোকাস করে; আমি সি ++ 14/17-এ প্রবর্তিত (ছোট) পরিবর্তনগুলি প্রতিফলিত করতে এটি আপডেট করতে পারি। আপনার উন্নতির জন্য কোনও মন্তব্য বা পরামর্শ থাকলে দয়া করে আমাকে জানান!
এমপিএটার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.