আমি একই জিনিস জানতে চেয়েছিলাম, তাই আমি এটি মাপা। আমার বাক্সে (এএমডি এফএক্স (টিএম) -8150 আট-কোর প্রসেসরটি 3.612361 গিগাহার্জ) এ, একটি আনলক করা মিটেক্সকে লক এবং আনলক করছে যা তার নিজস্ব ক্যাশে লাইনে রয়েছে এবং ইতিমধ্যে ক্যাশে রয়েছে, 47 টি ঘড়ি (13 এনএস) লাগে takes
দুটি কোরের মধ্যে সিঙ্ক্রোনাইজেশনের কারণে (আমি সিপিইউ # 0 এবং # 1 ব্যবহার করেছি), আমি কেবলমাত্র দুটি লম্বায় প্রতি 102 এনএসে একবার লক / আনলক জোড় কল করতে পারি, তাই প্রতি 51 এনএস একবার, যার থেকে সিদ্ধান্ত নেওয়া যায় যে এটি মোটামুটি 38 লাগে পরবর্তী থ্রেডটি আবার লক করতে পারে তার আগে কোনও থ্রেড একটি আনলক করার পরে পুনরুদ্ধার করতে এনএস।
আমি যে প্রোগ্রামটি তদন্ত করতে ব্যবহার করেছি এটি এখানে পাওয়া যাবে:
https://github.com/CarloWood/ai-statefultask-testsuite/blob/b69b112e2e91d35b56a39f41809d3e3de2f9e4b8/src/mutex_test.cxx
মনে রাখবেন যে এটিতে আমার বাক্সের জন্য নির্দিষ্ট কয়েকটি হার্ডকোডযুক্ত মান রয়েছে (এক্সরেঞ্জ, ইরেঞ্জ এবং আরডিএসসি ওভারহেড), সুতরাং এটি আপনার পক্ষে কাজ করার আগে আপনাকে সম্ভবত এটি ব্যবহার করতে হবে।
এই রাজ্যে এটি তৈরি করা গ্রাফটি হ'ল:
এটি নীচের কোডে বেঞ্চমার্কের ফলাফল দেখায়:
uint64_t do_Ndec(int thread, int loop_count)
{
uint64_t start;
uint64_t end;
int __d0;
asm volatile ("rdtsc\n\tshl $32, %%rdx\n\tor %%rdx, %0" : "=a" (start) : : "%rdx");
mutex.lock();
mutex.unlock();
asm volatile ("rdtsc\n\tshl $32, %%rdx\n\tor %%rdx, %0" : "=a" (end) : : "%rdx");
asm volatile ("\n1:\n\tdecl %%ecx\n\tjnz 1b" : "=c" (__d0) : "c" (loop_count - thread) : "cc");
return end - start;
}
দুটি আরডিএসসি কলগুলি `মুটেক্স 'লক এবং আনলক করতে যে ঘড়িগুলি লাগবে তা পরিমাপ করে (আমার বাক্সে আরডিএসসি কলগুলির জন্য 39 টি ঘড়ির ওভারহেড সহ)। তৃতীয় asm একটি বিলম্ব লুপ হয়। দেরী লুপের আকার থ্রেড 1 এর চেয়ে থ্রেড 1 এর চেয়ে 1 কাউন্ট ছোট, সুতরাং থ্রেড 1 কিছুটা দ্রুত is
উপরের ফাংশনটি 100,000 আকারের শক্ত লুপে ডাকা হয়। থ্রেড 1 এর জন্য ফাংশনটি সামান্য দ্রুত হওয়া সত্ত্বেও, মিউটেক্সে কল করার কারণে উভয় লুপ সিঙ্ক্রোনাইজ হয়। এটি গ্রাফটিতে এই বাস্তব থেকে দৃশ্যমান যে লক / আনলক জোড়ের জন্য পরিমাপ করা ঘড়ির সংখ্যা থ্রেড 1 এর জন্য কিছুটা বড়, এটির নীচে লুপের সংক্ষিপ্ত বিলম্বের জন্য অ্যাকাউন্টবদ্ধ হতে পারে।
উপরের গ্রাফের নীচে ডান পয়েন্টটি হ'ল একটি বিলম্ব লুপ_কাউন্ট 150 এর একটি পরিমাপ এবং তারপরে নীচের পয়েন্টগুলি অনুসরণ করে বাম দিকে, প্রতিটি পরিমাপের দ্বারা লুপ_কাউন্টটি হ্রাস পাবে। এটি 77 হয়ে গেলে ফাংশনটি উভয় থ্রেডে প্রতি 102 এনএস বলা হয়। পরবর্তী সময়ে যদি লুপ_কাউন্টটি আরও কমানো হয় তবে থ্রেডগুলি সিঙ্ক্রোনাইজ করা আর সম্ভব নয় এবং মুটেক্স আসলে বেশিরভাগ সময় লক করা শুরু করে, ফলস্বরূপ লক / আনলক করতে যে পরিমাণ ঘড়ি লাগবে তা বৃদ্ধি পায়। এছাড়াও ফাংশন কলের গড় সময় এই কারণে বৃদ্ধি পায়; সুতরাং প্লট পয়েন্টগুলি এখন উপরে এবং ডানদিকে আবার।
এ থেকে আমরা উপসংহারে আসতে পারি যে প্রতি 50 এনএসে একটি মিউটেক্সকে লক করা এবং আনলক করা আমার বাক্সে কোনও সমস্যা নয়।
আমার সমস্ত উপসংহারে সব মিলিয়ে ওপি-র প্রশ্নের উত্তরটি হ'ল যতক্ষণ পর্যন্ত কম বিতর্ক হয় তার ফলাফল হিসাবে আরও মুটেক্স যুক্ত করা আরও ভাল।
যতটা সম্ভব সংক্ষিপ্তভাবে লক করার চেষ্টা করুন। এগুলিকে রাখার একমাত্র কারণ - একটি লুপের বাইরে যদি লুপটি প্রতি 100 এনএস একবারে (বা বরং একই সময়ে 50 টি এনএস এ লুপটি চালাতে চায় এমন থ্রেডের সংখ্যা) বা 13 এনএস বারের চেয়ে দ্রুত লুপ হয় লুপের আকারটি আপনি বিতর্কিত হওয়ার চেয়ে বেশি বিলম্ব করেছেন।
সম্পাদনা: আমি এখন এই বিষয়টিতে আরও অনেক জ্ঞাতযোগ্য হয়েছি এবং আমি এখানে উপসংহারে উপস্থাপনের বিষয়ে সন্দেহ শুরু করি। প্রথমত, সিপিইউ 0 এবং 1 হাইপার-থ্রেডযুক্ত পরিণত হয়; যদিও এএমডি ৮ টি বাস্তব কোর রয়েছে বলে দাবি করেছে তবে অবশ্যই খুব মজাদার কিছু আছে কারণ অন্য দুটি কোরের মধ্যে বিলম্ব অনেক বড় (যেমন, 0 এবং 1 একটি জোড় তৈরি করে, যেমন 2 এবং 3, 4 এবং 5 এবং 6 এবং 7 করে )। দ্বিতীয়ত, স্টাডি :: মিউটেক্সটি এমনভাবে প্রয়োগ করা হয় যে সিস্টেম কল করার আগে এটি যখন কিছুক্ষণের জন্য লক স্পিন করে তখন তা যখন তাত্ক্ষণিকভাবে কোনও মিটেক্সে লকটি অর্জন করতে ব্যর্থ হয় (যা সন্দেহ নেই যে খুব ধীর হবে)। সুতরাং আমি এখানে যা পরিমাপ করেছি তা হ'ল পরম আদর্শ সিটেশন এবং অনুশীলনে লক করা এবং আনলক করাতে লক / আনলক প্রতি মারাত্মকভাবে আরও বেশি সময় লাগতে পারে।
নীচের লাইনটি, একটি মিউটেক্সকে পরমাণু দিয়ে প্রয়োগ করা হয়। কোরগুলির মধ্যে পারমাণবিকতা সিঙ্ক্রোনাইজ করতে একটি অভ্যন্তরীণ বাস অবশ্যই লক করে রাখতে হবে যা সংশ্লিষ্ট ক্যাশে লাইনটি কয়েক শতাধিক ঘড়ির চক্রের জন্য জমা করে দেয়। লকটি পাওয়া যায় না এমন ক্ষেত্রে থ্রেডটি ঘুমানোর জন্য একটি সিস্টেম কল করা উচিত; এটি অবশ্যই অত্যন্ত ধীর (সিস্টেম কলগুলি 10 মিরকোসেকেন্ডের ক্রমযুক্ত)। সাধারণত এটি আসলে কোনও সমস্যা নয় কারণ সেই থ্রেডটি যেভাবেই ঘুমাতে হবে - তবে এটি উচ্চ বিরোধের সাথে সমস্যা হতে পারে যেখানে কোনও থ্রেড সময়টির জন্য লকটি গ্রহণ করতে পারে না যখন এটি সাধারণত স্পিন করে এবং সিস্টেম কল করে, কিন্তু পারে খুব শীঘ্রই সেখানে লক নিতে। উদাহরণস্বরূপ, যদি বেশ কয়েকটি থ্রেড একটি শক্ত লুপে একটি মিউটেক্সকে লক করে এবং আনলক করে এবং প্রতিটি লকটি 1 মাইক্রোসেকেন্ড বা তার জন্য রাখে, তাহলে এগুলি যে তারা নিরন্তর ঘুমিয়ে পড়েছে এবং আবার জেগে উঠেছে এ কারণে তারা প্রচুর পরিমাণে কমে যেতে পারে। এছাড়াও, একবার একবার থ্রেড ঘুমায় এবং অন্য থ্রেডটি জাগ্রত হয়, সেই থ্রেডটি একটি সিস্টেম কল করতে হয় এবং delayed 10 মাইক্রোসেকেন্ডে বিলম্বিত হয়; এই বিলম্বটি এভাবে যখন মুদ্রাটি আনলক করার সময় ঘটে যখন অন্য থ্রেড কার্নেলের মধ্যে সেই মুটেক্সের জন্য অপেক্ষা করতে থাকে (কাটানোর পরে খুব বেশি সময় নেয়)।