আমাকে কেউ বলতে পারবেন যে std :: atomic :: is_lock_free () স্থির পাশাপাশি কন্টেক্সেক্সের নয়? এটি অ-স্থিতিশীল এবং / বা অ-কনসেক্সেক্স হিসাবে থাকা আমার পক্ষে বোধগম্য নয়।
আমাকে কেউ বলতে পারবেন যে std :: atomic :: is_lock_free () স্থির পাশাপাশি কন্টেক্সেক্সের নয়? এটি অ-স্থিতিশীল এবং / বা অ-কনসেক্সেক্স হিসাবে থাকা আমার পক্ষে বোধগম্য নয়।
উত্তর:
সিপ্রেফারেন্স হিসাবে ব্যাখ্যা করা হয়েছে :
স্ট্যান্ড :: অ্যাটমিক_ফ্লেগ ব্যতীত সমস্ত পারমাণবিক প্রকার লক-ফ্রি পারমাণবিক সিপিইউ নির্দেশাবলীর পরিবর্তে মুটেক্সেস বা অন্যান্য লকিং অপারেশন ব্যবহার করে প্রয়োগ করা যেতে পারে। পারমাণবিক প্রকারগুলিকে মাঝে মাঝে লক-মুক্ত থাকারও অনুমতি দেওয়া হয়, উদাহরণস্বরূপ যদি কোনও প্রান্তিক মেমরির প্রবেশাধিকার যদি কোনও নির্দিষ্ট আর্কিটেকচারে প্রাকৃতিকভাবে পারমাণবিক হয় তবে একই ধরণের মিস্যালাইনযুক্ত বস্তুগুলিকে লক ব্যবহার করতে হবে।
সি ++ স্ট্যান্ডার্ড সুপারিশ করে (তবে এটির প্রয়োজন হয় না) লক-ফ্রি পারমাণবিক ক্রিয়াকলাপগুলি ঠিকানা-মুক্তও, যা ভাগ করে নেওয়া মেমরি ব্যবহার করে প্রক্রিয়াগুলির মধ্যে যোগাযোগের জন্য উপযুক্ত।
একাধিক অন্য দ্বারা উল্লিখিত হিসাবে, std::is_always_lock_free
আপনি সত্যিই যা খুঁজছেন তা হতে পারে।
সম্পাদনা: স্পষ্ট করার জন্য, সি ++ অবজেক্টের ধরণের একটি প্রান্তিককরণ মান রয়েছে যা তাদের দৃষ্টান্তগুলির ঠিকানাগুলিকে কেবলমাত্র দুটি ( [basic.align]
) পাওয়ারের কয়েকটি নির্দিষ্ট গুণকের মধ্যে সীমাবদ্ধ করে । এই প্রান্তিককরণের মানগুলি মৌলিক প্রকারের জন্য বাস্তবায়ন-সংজ্ঞায়িত, এবং প্রকারের আকারের সমান হওয়া দরকার না। হার্ডওয়্যার আসলে যা সমর্থন করতে পারে তার চেয়ে এগুলি আরও কঠোর হতে পারে।
উদাহরণস্বরূপ, x86 (বেশিরভাগ) স্বাক্ষরবিহীন অ্যাক্সেসগুলি সমর্থন করে। তবে, আপনি বেশিরভাগ সংকলক alignof(double) == sizeof(double) == 8
x86 এর সাথে পেয়ে যাবেন যেহেতু স্বাক্ষরযুক্ত অ্যাক্সেসগুলির অনেকগুলি অসুবিধাগুলি রয়েছে (গতি, ক্যাশিং, পারমাণবিকতা ...)। তবে উদাহরণস্বরূপ #pragma pack(1) struct X { char a; double b; };
বা alignas(1) double x;
আপনাকে "স্বাক্ষরবিহীন" double
গুলি রাখতে দেয়। সুতরাং যখন সিপ্রেফারেন্স "অ্যালাইন্ডড মেমরি অ্যাক্সেসস" সম্পর্কে কথা বলবে, সম্ভবত এটি হার্ডওয়ারের জন্য প্রকারের প্রাকৃতিক প্রান্তিককরণের ক্ষেত্রে, সি ++ টাইপটি এমনভাবে ব্যবহার না করা হয় যা তার প্রান্তিককরণের প্রয়োজনীয়তাগুলির বিপরীতে থাকে (যা ইউবি হবে)।
এখানে আরও তথ্য: x86- এ সফল স্বাক্ষরিত অ্যাক্সেসগুলির আসল প্রভাবটি কী?
নীচের @ পিটার কর্ডসের অন্তর্দৃষ্টিপূর্ণ মন্তব্যগুলিও দেখুন!
alignof(double)==4
। তবে std::atomic<double>
এখনও alignof() = 8
রানটাইমে প্রান্তিককরণ পরীক্ষা করার পরিবর্তে রয়েছে। এমন একটি প্যাকযুক্ত কাঠামো ব্যবহার করা যা পরমাণুকে আন্ডার-অ্যালাইজ করে এবিআইকে বিভক্ত করে এবং সমর্থন করে না। (32-বিট x86 এর জন্য জিসিসি 8-বাইট অবজেক্টগুলিকে প্রাকৃতিক প্রান্তিককরণ দিতে পছন্দ করে তবে স্ট্রাক্ট-প্যাকিং নিয়মগুলি ওভাররাইড করে এবং কেবলমাত্র alignof(T)
i386 সিস্টেম ভি এর উপর ভিত্তি করে । জি ++ এর মধ্যে একটি বাগ থাকে যেখানে atomic<int64_t>
কাঠামোর ভিতরে পারমাণবিক নাও হতে পারে কারণ এটি সবেমাত্র অনুমান করা হয়েছে। জিসিসি (সি এর জন্য নয় সি ++ এর জন্য) এখনও এই বাগ রয়েছে!)
std::atomic_ref<double>
হয় double
পুরোপুরি আন্ডার- অ্যালাইন্টডকে প্রত্যাখ্যান করবে বা প্ল্যাটফর্মগুলিতে রানটাইম সময়ে প্রান্তিককরণ পরীক্ষা করবে যেখানে এটি সরল জন্য বৈধ double
এবং int64_t
প্রাকৃতিকভাবে প্রান্তিককরণের চেয়ে কম হবে। (কারণ atomic_ref<T>
যে কোনও বস্তুটিকে সমতল হিসাবে ঘোষণা করা হয়েছিল তার উপর কাজ করে T
এবং কেবলমাত্র alignof(T)
এটির অতিরিক্ত প্রান্তিককরণ দেওয়ার সুযোগ ছাড়াই একটি ন্যূনতম প্রান্তিককরণ থাকে ))
_Atomic int64_t
স্রোতের সাথে সংকলিত হয়ে ছিঁড়ে যাওয়া দেখায় gcc -m32
। যাইহোক, আমার বক্তব্যটি হ'ল আসল সংকলকগুলি নীচে-প্রান্তিকৃত পারমাণবিক সমর্থন করে না, এবং রানটাইম চেকগুলি (এখনও?) করবেন না, তাই #pragma pack
বা __attribute__((packed))
কেবল অ-পারমাণবিকতার দিকে পরিচালিত করবে; বস্তুগুলি এখনও তাদের রিপোর্ট করবে lock_free
।
is_lock_free()
হ'ল বাস্তবায়নগুলি বাস্তবে যেভাবে করা হয় তার থেকে আলাদাভাবে কাজ করতে দেয় ; এইচডাব্লু-সমর্থিত পারমাণবিক নির্দেশাবলী ব্যবহার করতে বা একটি লক ব্যবহার করতে প্রকৃত প্রান্তিককরণের ভিত্তিতে রানটাইম চেক সহ।
আপনি ব্যবহার করতে পারেন std::is_always_lock_free
is_lock_free
প্রকৃত সিস্টেমের উপর নির্ভর করে এবং সংকলনের সময় নির্ধারণ করা যায় না।
প্রাসঙ্গিক ব্যাখ্যা:
পারমাণবিক প্রকারগুলিকে মাঝে মাঝে লক-মুক্ত থাকারও অনুমতি দেওয়া হয়, যেমন যদি কোনও প্রান্তিক মেমরি অ্যাক্সেসগুলি কোনও নির্দিষ্ট আর্কিটেকচারে প্রাকৃতিকভাবে পারমাণবিক হয় তবে একই ধরণের মিস্যালাইনযুক্ত বস্তুগুলিকে লক ব্যবহার করতে হবে।
std::numeric_limits<int>::max
আর্কিটেকচারের উপর নির্ভর করে, তবুও স্থির এবং constexpr
। আমি অনুমান করি যে
is_lock_free
অর্থহীন নয় যে কম্পাইলার উপর ।
আমি আমার উইন্ডোজ-পিসিতে ভিজ্যুয়াল স্টুডিও 2019 ইনস্টল করেছি এবং এই দেবেনভের একটি এআরএমভি 8-সংকলকও রয়েছে। এআরএমভি 8 আনইলাইনযুক্ত অ্যাক্সেসগুলিকে অনুমতি দেয় তবে তুলনা এবং অদলবদল, লকড অ্যাডস ইত্যাদি প্রান্তিককরণের জন্য বাধ্যতামূলক। এবং খাঁটি লোড / খাঁটি স্টোর ব্যবহার করে ldp
বা stp
(লোড-জুড়ি বা 32-বিট রেজিস্টারগুলির স্টোর-জুড়ি) কেবল প্রাকৃতিকভাবে সারিবদ্ধ থাকলেই কেবল পারমাণবিক হওয়ার নিশ্চয়তা দেওয়া হয়।
সুতরাং আমি_সামান্য পারমাণবিক-পয়েন্টারটির জন্য কি_স_লোক_ফ্রি () কী দেয় তা পরীক্ষা করতে আমি একটি ছোট্ট প্রোগ্রাম লিখেছি। সুতরাং এখানে কোড:
#include <atomic>
#include <cstddef>
using namespace std;
bool isLockFreeAtomic( atomic<uint64_t> *a64 )
{
return a64->is_lock_free();
}
এবং এটি হ'ল লকফ্রিআউটমিকের বিযুক্তি
|?isLockFreeAtomic@@YA_NPAU?$atomic@_K@std@@@Z| PROC
movs r0,#1
bx lr
ENDP
এটা ঠিক returns true
, ওরফে 1
।
এই প্রয়োগটি ব্যবহার করতে বেছে নেয় alignof( atomic<int64_t> ) == 8
যাতে প্রতিটি atomic<int64_t>
সঠিকভাবে সংযুক্ত থাকে। এটি প্রতিটি লোড এবং স্টোরটিতে রানটাইম প্রান্তিককরণ চেকের প্রয়োজনীয়তা এড়ায়।
(সম্পাদক এর নোট: এই দেখা যায়; সবচেয়ে বাস্তব জীবনের সি ++ বাস্তবায়নের এই ভাবে কাজ এই জন্যই হয়। std::is_always_lock_free
তাই উপকারী কারণ এটি সাধারণত ধরনের যেখানে জন্য সত্যি is_lock_free()
কি কখনো সত্য।)
atomic<uint64_t>
এবং alignof() == 8
তাই রানটাইমে তাদের প্রান্তিককরণ পরীক্ষা করতে হবে না। এই পুরানো এপিআই তাদের এগুলি না করার বিকল্প দেয় তবে বর্তমান এইচডাব্লুটিতে এটি কেবলমাত্র প্রান্তিককরণের প্রয়োজন হয় (অন্যথায় ইউবি, যেমন অ-পরমাণু নয়)) এমনকি 32-বিট কোডে যেখানে int64_t
কেবল 4-বাইট প্রান্তিককরণ থাকতে পারে, সেখানে atomic<int64_t>
8-বাইট প্রয়োজন। অন্য উত্তরে আমার মন্তব্যগুলি
alignof
হার্ডওয়্যারটির "ভাল" প্রান্তিককরণের মতো কোনও মৌলিক ধরণের জন্য মান নির্ধারণ করে, তবে is_lock_free
সর্বদা থাকবে true
(এবং তাই হবে is_always_lock_free
)। আপনার সংকলক এখানে ঠিক এটি করে। তবে এপিআই বিদ্যমান তাই অন্যান্য সংকলকগণ বিভিন্ন কাজ করতে পারে।
alignof(std::atomic<double>) == 1
(তাই সি ++ অর্থে কোনও "স্বাক্ষরিত অ্যাক্সেস" থাকবে না, সুতরাং কোনও ইউবি নেই), এমনকি যদি হার্ডওয়্যার কেবল double
4 বা তার জন্য লক-মুক্ত পারমাণবিক ক্রিয়াকলাপের গ্যারান্টি দিতে পারে 8 বাইট সীমানা। সংকলকটি তখন স্বাক্ষরবিহীন ক্ষেত্রে লকগুলি ব্যবহার করতে হবে (এবং is_lock_free
অবজেক্টের উদাহরণের মেমরির অবস্থানের উপর নির্ভর করে যথাযথ বুলিয়ান মানটি ফিরিয়ে দিতে হবে )।
is_always_lock_free
?