জাভাতে মেমরি বেড়াগুলি কীসের জন্য ব্যবহৃত হয়?


18

বুঝতে চেষ্টা যতক্ষণ SubmissionPublisher( জাভা SE 10, OpenJDK মধ্যে সোর্স কোড | ডক্স ), একটি নতুন শ্রেণী সংস্করণ 9 জাভা SE এ যোগ করেছেন বাস্তবায়িত হয়েছে, আমি কয়েক API কল করার জন্য জুড়ে পদস্খলিত VarHandleআমি এর পূর্বে সচেতন ছিলাম না:

fullFence, acquireFence, releaseFence, loadLoadFenceএবং storeStoreFence

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

  1. মেমরি বাধা পড়া এবং লেখার ক্রিয়াকলাপ সংক্রান্ত সীমাবদ্ধতাগুলি পুনরায় সাজিয়ে তুলছে।

  2. মেমরি বাধা দুটি প্রধান বিভাগে শ্রেণিবদ্ধ করা যেতে পারে: একমুখী এবং দ্বিদ্বিচারী মেমরি বাধা, তার উপর নির্ভর করে তারা পড়তে বা লিখতে বা উভয় ক্ষেত্রেই বাধা নির্ধারণ করে।

  3. সি ++ বিভিন্ন ধরণের মেমরি বাধা সমর্থন করে , তবে এটি সরবরাহিতগুলির সাথে মেলে না VarHandleতবে, মেমরি উপলব্ধ বাধা কিছু VarHandleপ্রদান ক্রম প্রভাব যে সামঞ্জস্যপূর্ণ তাদের সংশ্লিষ্ট সি ++ মেমরির বাধা রয়েছে।

    • #fullFence সাথে সামঞ্জস্যপূর্ণ atomic_thread_fence(memory_order_seq_cst)
    • #acquireFence সাথে সামঞ্জস্যপূর্ণ atomic_thread_fence(memory_order_acquire)
    • #releaseFence সাথে সামঞ্জস্যপূর্ণ atomic_thread_fence(memory_order_release)
    • #loadLoadFenceএবং #storeStoreFenceকোনও উপযুক্ত সি ++ কাউন্টার অংশ নেই

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

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

আমার অনুমানগুলি কি সঠিক? যদি তা হয় তবে আমার ফলাফলগুলি হ'ল:

  1. মেমরি বাধা উপলব্ধ কি VarHandleকোনও ধরণের মেমরি সিঙ্ক্রোনাইজেশন কারণ?

  2. তারা মেমরি সিঙ্ক্রোনাইজেশন ঘটায় বা না তা নির্বিশেষে, জাভাতে পুনরায় ক্রমাগত সীমাবদ্ধতাগুলি কী কার্যকর হতে পারে? জাভা মেমোরি মডেলটি ইতিমধ্যে অস্থির ক্ষেত্রগুলি, লকগুলি বা এর VarHandleমতো ক্রিয়াকলাপের #compareAndSetসাথে জড়িত থাকার সময় অর্ডার সম্পর্কিত কিছু খুব দৃ strong় গ্যারান্টি দেয় ।

আপনি যদি একটি উদাহরণ সন্ধান করছেন: পূর্বোক্ত BufferedSubscription, SubmissionPublisher(উপরের লিঙ্কযুক্ত উত্স) এর একটি অভ্যন্তর শ্রেণি 1079 লাইনে একটি সম্পূর্ণ বেড়া স্থাপন করেছে (ফাংশন growAndAdd; লিঙ্কযুক্ত ওয়েবসাইটটি খণ্ড সনাক্তকারীকে সমর্থন করে না, কেবল এটির জন্য সিটিআরএল + এফ )। তবে এটি কীসের জন্য তা আমার পক্ষে অস্পষ্ট।


1
আমি উত্তর দেওয়ার চেষ্টা করেছি, তবে এটি খুব সাধারণভাবে বলতে গেলে এগুলি বিদ্যমান কারণ জাভা যা আছে তার চেয়ে লোকেরা দুর্বল মোড চায় । অর্ডার আরোহী, এই হবে: plain -> opaque -> release/acquire -> volatile (sequential consistency)
ইউজিন

উত্তর:


11

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

আপনাকে প্রথমে বুঝতে হবে:

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

এটি কাজ চলছে।

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

আর একটি উদাহরণ হ'ল (জাভাতে) আপনি volatileথামা থামাতে / শুরু করতে থ্রেডগুলি নিয়ন্ত্রণ করতে একটি পতাকা চান । আপনি জানেন, ধ্রুপদী:

volatile boolean stop = false; // on thread writes, one thread reads this    

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

একটি থ্রেড নিরাপদ পতাকা, কিন্তু উদ্বায়ী না? হ্যাঁ, ঠিক: VarHandle::set/getOpaque

এবং আপনি প্রশ্ন করবেন কেন কারও উদাহরণস্বরূপ এর প্রয়োজন হতে পারে? ক দ্বারা পিগি-সমর্থনযুক্ত সমস্ত পরিবর্তনগুলির সাথে প্রত্যেকেই আগ্রহী নয় volatile

আসুন দেখি আমরা কীভাবে এটি জাভাতে অর্জন করব। প্রথম সব, এই ধরনের বহিরাগত কিছু ইতিমধ্যে এপিআই অস্তিত্ব: AtomicInteger::lazySet। এটি জাভা মেমোরি মডেলটিতে অনির্ধারিত এবং এর কোনও স্পষ্ট সংজ্ঞা নেই ; তবুও লোকেরা এটি ব্যবহার করেছে (এলএমএএক্স, আফিক বা আরও পড়ার জন্য এটি )। এই প্রোগ্রামটিতে, AtomicInteger::lazySetহয় VarHandle::releaseFence(অথবা VarHandle::storeStoreFence)।


এর উত্তর দেওয়ার চেষ্টা করি কারও এগুলি কেন প্রয়োজন ?

জেএমএমের ক্ষেত্রটি অ্যাক্সেস করার মূলত দুটি উপায় রয়েছে: প্লেইন এবং অস্থির (যা ক্রমানুসারে ধারাবাহিকতার গ্যারান্টি দেয় )। এই সমস্ত পদ্ধতি যা আপনি উল্লেখ করেছেন সেগুলি এই দুটিয়ের মধ্যে কিছু আনার জন্য রয়েছে - শব্দার্থ প্রকাশ / অর্জন ; আমি অনুমান করি যে এখানে লোকেরা আসলে এটির প্রয়োজন।

একটি এমনকি আরো থেকে শিথিলকরণ মুক্তি / অর্জন হবে অস্বচ্ছ , যা আমি এখনও সম্পূর্ণরূপে বুঝতে চেষ্টা করছি


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


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

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

1
@ পিটার কর্ডস: জাভাটির volatileপাঁচ বছর পরে মূল শব্দটি থাকা প্রথম সি সংস্করণটি C99 ছিল , তবে এটিতে এখনও কার্যকর শব্দার্থবিজ্ঞানের অভাব ছিল, এমনকি সি ++ 03 এর কোনও মেমোরি মডেল নেই। যে বিষয়গুলিতে সি ++ "আণবিক" বলে তা জাভা থেকেও অনেক কম বয়সী। এবং volatileকীওয়ার্ডটি পারমাণবিক আপডেটগুলিও বোঝায় না। তাহলে এর নামকরণ কেন করা উচিত।
হোলার

1
@ পিটারকর্ডস সম্ভবত, আমি এটির সাথে বিভ্রান্ত করছি restrict, তবে আমার মনে আছে এমন সময়গুলি যখন আমাকে __volatileএকটি নন-কীওয়ার্ড সংকলক এক্সটেনশন ব্যবহার করতে লিখতে হয়েছিল। সুতরাং সম্ভবত, এটি পুরোপুরি C89 বাস্তবায়ন করেনি? আমাকে বলুন না আমি যে বয়সী। জাভা 5 এর আগে volatileসি এর অনেক কাছাকাছি ছিল কিন্তু জাভাতে কোনও এমএমআইও ছিল না, সুতরাং এর উদ্দেশ্যটি সর্বদা বহু-থ্রেডিং ছিল, তবে জাভা 5-এর পূর্ববর্তী শব্দার্থ সেটির জন্য খুব কার্যকর ছিল না। সুতরাং শব্দার্থবিজ্ঞানের মতো প্রকাশ / অর্জন যোগ করা হয়েছিল, তবে এখনও এটি পারমাণবিক নয় (পারমাণবিক আপডেটগুলি এটির উপরে নির্মিত একটি অতিরিক্ত বৈশিষ্ট্য)।
হোলার

2
@Eugene সংক্রান্ত এই , আমার উদাহরণ লকিং যা অর্জন হবে জন্য CA গুলির ব্যবহার করার জন্য নির্দিষ্ট ছিল। একটি কাউন্টডাউন ল্যাচ রিলিজ সিমেন্টিক সহ পরমাণু হ্রাস সহ্য করবে, তার পরে থ্রেড শূন্যে পৌঁছে একটি অর্জন বেড়া প্রবেশ করিয়ে এবং চূড়ান্ত ক্রিয়া সম্পাদন করে। অবশ্যই, পারমাণবিক আপডেটের জন্য অন্যান্য ক্ষেত্রেও রয়েছে যেখানে পুরো বেড়া প্রয়োজন।
হোলগার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.