কেন std :: পরমাণু <T> :: is_lock_free () স্থির পাশাপাশি কন্টেক্সেক্সের নয়?


9

আমাকে কেউ বলতে পারবেন যে std :: atomic :: is_lock_free () স্থির পাশাপাশি কন্টেক্সেক্সের নয়? এটি অ-স্থিতিশীল এবং / বা অ-কনসেক্সেক্স হিসাবে থাকা আমার পক্ষে বোধগম্য নয়।


3
আপনি কি সচেতন is_always_lock_free?
মাইক ভ্যান ডাইক

3
আমি সেখানে "প্রান্তিককরণ" নিক্ষেপ করতে যাচ্ছি।
ম্যাক্স ল্যাংফোফ

@ ম্যাক্সলানঘফ আপনার অর্থ কি সমস্ত দৃষ্টিকোণ একইভাবে সারিবদ্ধ হবে না?
কৌতূহলী

1
মাইক, না, আমি সচেতন ছিলাম না, তবে এই ইঙ্গিতটির জন্য ধন্যবাদ; এটা আসলেই আমার জন্য উপকারী. তবে আমি নিজেকে জিজ্ঞাসা করছি কেন ইস্কলক_ফ্রি () এবং ইস_লওয়েজ_লোক_ফ্রি এর মধ্যে কেন সিদ্ধান্ত আছে? এটি স্বাক্ষরবিহীন পরমাণুর কারণে নাও হতে পারে, অন্যরা এখানে প্রস্তাবিত, যেহেতু ভাষাটি স্বাক্ষরিত অ্যাক্সেসগুলি যে কোনওভাবেই সংজ্ঞায়িত আচরণ করতে সংজ্ঞায়িত করে।
বোনিটা মন্টেরো

উত্তর:


10

সিপ্রেফারেন্স হিসাবে ব্যাখ্যা করা হয়েছে :

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

সি ++ স্ট্যান্ডার্ড সুপারিশ করে (তবে এটির প্রয়োজন হয় না) লক-ফ্রি পারমাণবিক ক্রিয়াকলাপগুলি ঠিকানা-মুক্তও, যা ভাগ করে নেওয়া মেমরি ব্যবহার করে প্রক্রিয়াগুলির মধ্যে যোগাযোগের জন্য উপযুক্ত।

একাধিক অন্য দ্বারা উল্লিখিত হিসাবে, std::is_always_lock_freeআপনি সত্যিই যা খুঁজছেন তা হতে পারে।


সম্পাদনা: স্পষ্ট করার জন্য, সি ++ অবজেক্টের ধরণের একটি প্রান্তিককরণ মান রয়েছে যা তাদের দৃষ্টান্তগুলির ঠিকানাগুলিকে কেবলমাত্র দুটি ( [basic.align]) পাওয়ারের কয়েকটি নির্দিষ্ট গুণকের মধ্যে সীমাবদ্ধ করে । এই প্রান্তিককরণের মানগুলি মৌলিক প্রকারের জন্য বাস্তবায়ন-সংজ্ঞায়িত, এবং প্রকারের আকারের সমান হওয়া দরকার না। হার্ডওয়্যার আসলে যা সমর্থন করতে পারে তার চেয়ে এগুলি আরও কঠোর হতে পারে।

উদাহরণস্বরূপ, x86 (বেশিরভাগ) স্বাক্ষরবিহীন অ্যাক্সেসগুলি সমর্থন করে। তবে, আপনি বেশিরভাগ সংকলক alignof(double) == sizeof(double) == 8x86 এর সাথে পেয়ে যাবেন যেহেতু স্বাক্ষরযুক্ত অ্যাক্সেসগুলির অনেকগুলি অসুবিধাগুলি রয়েছে (গতি, ক্যাশিং, পারমাণবিকতা ...)। তবে উদাহরণস্বরূপ #pragma pack(1) struct X { char a; double b; };বা alignas(1) double x;আপনাকে "স্বাক্ষরবিহীন" doubleগুলি রাখতে দেয়। সুতরাং যখন সিপ্রেফারেন্স "অ্যালাইন্ডড মেমরি অ্যাক্সেসস" সম্পর্কে কথা বলবে, সম্ভবত এটি হার্ডওয়ারের জন্য প্রকারের প্রাকৃতিক প্রান্তিককরণের ক্ষেত্রে, সি ++ টাইপটি এমনভাবে ব্যবহার না করা হয় যা তার প্রান্তিককরণের প্রয়োজনীয়তাগুলির বিপরীতে থাকে (যা ইউবি হবে)।

এখানে আরও তথ্য: x86- এ সফল স্বাক্ষরিত অ্যাক্সেসগুলির আসল প্রভাবটি কী?

নীচের @ পিটার কর্ডসের অন্তর্দৃষ্টিপূর্ণ মন্তব্যগুলিও দেখুন!


1
32-বিট x86 হ'ল আপনি যেখানে এবিআই পেয়েছেন তার একটি দুর্দান্ত উদাহরণ alignof(double)==4। তবে std::atomic<double>এখনও alignof() = 8রানটাইমে প্রান্তিককরণ পরীক্ষা করার পরিবর্তে রয়েছে। এমন একটি প্যাকযুক্ত কাঠামো ব্যবহার করা যা পরমাণুকে আন্ডার-অ্যালাইজ করে এবিআইকে বিভক্ত করে এবং সমর্থন করে না। (32-বিট x86 এর জন্য জিসিসি 8-বাইট অবজেক্টগুলিকে প্রাকৃতিক প্রান্তিককরণ দিতে পছন্দ করে তবে স্ট্রাক্ট-প্যাকিং নিয়মগুলি ওভাররাইড করে এবং কেবলমাত্র alignof(T)i386 সিস্টেম ভি এর উপর ভিত্তি করে । জি ++ এর মধ্যে একটি বাগ থাকে যেখানে atomic<int64_t>কাঠামোর ভিতরে পারমাণবিক নাও হতে পারে কারণ এটি সবেমাত্র অনুমান করা হয়েছে। জিসিসি (সি এর জন্য নয় সি ++ এর জন্য) এখনও এই বাগ রয়েছে!)
পিটার কর্ডেস

2
তবে সি ++ ২০ এর সঠিক প্রয়োগটি std::atomic_ref<double>হয় doubleপুরোপুরি আন্ডার- অ্যালাইন্টডকে প্রত্যাখ্যান করবে বা প্ল্যাটফর্মগুলিতে রানটাইম সময়ে প্রান্তিককরণ পরীক্ষা করবে যেখানে এটি সরল জন্য বৈধ doubleএবং int64_tপ্রাকৃতিকভাবে প্রান্তিককরণের চেয়ে কম হবে। (কারণ atomic_ref<T>যে কোনও বস্তুটিকে সমতল হিসাবে ঘোষণা করা হয়েছিল তার উপর কাজ করে Tএবং কেবলমাত্র alignof(T)এটির অতিরিক্ত প্রান্তিককরণ দেওয়ার সুযোগ ছাড়াই একটি ন্যূনতম প্রান্তিককরণ থাকে ))
পিটার কর্ডেস

2
দেখুন gcc.gnu.org/bugzilla/show_bug.cgi?id=62259 এখন সংশোধন করা হয়েছে আগে থেকে libstdc ++ বাগ জন্য, এবং gcc.gnu.org/bugzilla/show_bug.cgi?id=65146 , এখনও-ভাঙ্গা সি বাগ জন্য একটি সহ খাঁটি আইএসও সি 11 টেস্টকেস যা _Atomic int64_tস্রোতের সাথে সংকলিত হয়ে ছিঁড়ে যাওয়া দেখায় gcc -m32। যাইহোক, আমার বক্তব্যটি হ'ল আসল সংকলকগুলি নীচে-প্রান্তিকৃত পারমাণবিক সমর্থন করে না, এবং রানটাইম চেকগুলি (এখনও?) করবেন না, তাই #pragma packবা __attribute__((packed))কেবল অ-পারমাণবিকতার দিকে পরিচালিত করবে; বস্তুগুলি এখনও তাদের রিপোর্ট করবে lock_free
পিটার কর্ডেস

1
তবে হ্যাঁ, এর উদ্দেশ্য is_lock_free()হ'ল বাস্তবায়নগুলি বাস্তবে যেভাবে করা হয় তার থেকে আলাদাভাবে কাজ করতে দেয় ; এইচডাব্লু-সমর্থিত পারমাণবিক নির্দেশাবলী ব্যবহার করতে বা একটি লক ব্যবহার করতে প্রকৃত প্রান্তিককরণের ভিত্তিতে রানটাইম চেক সহ।
পিটার কর্ডেস

3

আপনি ব্যবহার করতে পারেন std::is_always_lock_free

is_lock_free প্রকৃত সিস্টেমের উপর নির্ভর করে এবং সংকলনের সময় নির্ধারণ করা যায় না।

প্রাসঙ্গিক ব্যাখ্যা:

পারমাণবিক প্রকারগুলিকে মাঝে মাঝে লক-মুক্ত থাকারও অনুমতি দেওয়া হয়, যেমন যদি কোনও প্রান্তিক মেমরি অ্যাক্সেসগুলি কোনও নির্দিষ্ট আর্কিটেকচারে প্রাকৃতিকভাবে পারমাণবিক হয় তবে একই ধরণের মিস্যালাইনযুক্ত বস্তুগুলিকে লক ব্যবহার করতে হবে।


1
std::numeric_limits<int>::maxআর্কিটেকচারের উপর নির্ভর করে, তবুও স্থির এবং constexpr। আমি অনুমান করি যে
উত্তরটিতে

1
লাইন-ফ্রি-নেস মূল্যায়ন বা রানটাইম সময় নয় এমন কোনও ভাষা নির্বিঘ্নিত আচরণের জন্য অ-স্বাক্ষরিত অ্যাক্সেসগুলি কী ভাষা সংজ্ঞায়িত করে না?
বোনিটা মন্টেরো

1
প্রান্তিককরণ এবং স্বাক্ষরবিহীন অ্যাক্সেসগুলির মধ্যে সিদ্ধান্ত নেওয়া কোনও অর্থবোধ করে না কারণ ভাষা পরবর্তীটি সংজ্ঞায়িত আচরণ হিসাবে সংজ্ঞায়িত করে।
বোনিটা মন্টেরো

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

1
আপনি পুরোপুরি নিশ্চিত হতে পারেন যে যদি একটি প্রান্তিককরণের প্রয়োজন হয় তবে কোনও পারমাণবিকের সঠিক প্রান্তিককরণ হবে।
বোনিটা মন্টেরো

1

আমি আমার উইন্ডোজ-পিসিতে ভিজ্যুয়াল স্টুডিও 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()কি কখনো সত্য।)


1
হ্যাঁ, বেশিরভাগ বাস্তবায়নগুলি দিতে পছন্দ করে atomic<uint64_t>এবং alignof() == 8তাই রানটাইমে তাদের প্রান্তিককরণ পরীক্ষা করতে হবে না। এই পুরানো এপিআই তাদের এগুলি না করার বিকল্প দেয় তবে বর্তমান এইচডাব্লুটিতে এটি কেবলমাত্র প্রান্তিককরণের প্রয়োজন হয় (অন্যথায় ইউবি, যেমন অ-পরমাণু নয়)) এমনকি 32-বিট কোডে যেখানে int64_tকেবল 4-বাইট প্রান্তিককরণ থাকতে পারে, সেখানে atomic<int64_t>8-বাইট প্রয়োজন। অন্য উত্তরে আমার মন্তব্যগুলি
পিটার কর্ডেস

বিভিন্ন শব্দের মধ্যে রাখুন: যদি কোনও সংকলক alignofহার্ডওয়্যারটির "ভাল" প্রান্তিককরণের মতো কোনও মৌলিক ধরণের জন্য মান নির্ধারণ করে, তবে is_lock_free সর্বদা থাকবে true(এবং তাই হবে is_always_lock_free)। আপনার সংকলক এখানে ঠিক এটি করে। তবে এপিআই বিদ্যমান তাই অন্যান্য সংকলকগণ বিভিন্ন কাজ করতে পারে।
ম্যাক্স ল্যাঙ্গোফ

1
আপনি বেশ নিশ্চিত হতে পারেন যে যদি ভাষাটি বলে যে স্বাক্ষরবিহীন অ্যাক্সেসের অনির্ধারিত আচরণ রয়েছে তবে সমস্ত পরমাণু সঠিকভাবে প্রান্তিককরণ করতে হবে। কোনও বাস্তবায়ন তার কারণে কোনও রানটাইম-চেক করবে না।
বোনিটা মন্টেরো

@ বনিটা মন্টেরো হ্যাঁ, তবে ভাষায় এমন কিছু নেই যা নিষিদ্ধ করে alignof(std::atomic<double>) == 1(তাই সি ++ অর্থে কোনও "স্বাক্ষরিত অ্যাক্সেস" থাকবে না, সুতরাং কোনও ইউবি নেই), এমনকি যদি হার্ডওয়্যার কেবল double4 বা তার জন্য লক-মুক্ত পারমাণবিক ক্রিয়াকলাপের গ্যারান্টি দিতে পারে 8 বাইট সীমানা। সংকলকটি তখন স্বাক্ষরবিহীন ক্ষেত্রে লকগুলি ব্যবহার করতে হবে (এবং is_lock_freeঅবজেক্টের উদাহরণের মেমরির অবস্থানের উপর নির্ভর করে যথাযথ বুলিয়ান মানটি ফিরিয়ে দিতে হবে )।
ম্যাক্স ল্যাংফোফ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.