লক স্টেটমেন্টটি কত ব্যয়বহুল?


111

আমি মাল্টি থ্রেডিং এবং সমান্তরাল প্রক্রিয়াজাতকরণ নিয়ে পরীক্ষা নিরীক্ষা করেছি এবং প্রক্রিয়াটির গতি সম্পর্কে কিছু মৌলিক গণনা এবং পরিসংখ্যান বিশ্লেষণ করার জন্য আমার একটি কাউন্টারের প্রয়োজন ছিল। আমার ক্লাসের একযোগে ব্যবহারে সমস্যা এড়াতে আমি আমার ক্লাসে একটি ব্যক্তিগত ভেরিয়েবলের লক স্টেটমেন্ট ব্যবহার করেছি:

private object mutex = new object();

public void Count(int amount)
{
 lock(mutex)
 {
  done += amount;
 }
}

তবে আমি ভাবছিলাম ... ভেরিয়েবল লক করা কত ব্যয়বহুল? কর্মক্ষমতা নেতিবাচক প্রভাব কি?


10
ভেরিয়েবল লক করা এত ব্যয়বহুল নয়; এটি একটি লক ভেরিয়েবলের অপেক্ষার যা আপনি এড়াতে চান।
গাবে

53
অন্য দৌড়ের শর্তটি অনুসরণ করতে ঘন্টা ব্যয় করার চেয়ে অনেক কম ব্যয়বহুল ;-)
ব্রোকেনগ্লাস

2
ভাল ... যদি কোনও লক ব্যয়বহুল হয় তবে আপনি প্রোগ্রামিং পরিবর্তন করে এগুলি এড়াতে চাইতে পারেন যাতে এটির জন্য কম লক প্রয়োজন। আমি এক ধরণের সিঙ্ক্রোনাইজেশন প্রয়োগ করতে পারি।
কিস সি বেকার

1
আমি আমার লক ব্লকগুলি থেকে প্রচুর কোড সরিয়ে নিয়ে পারফরম্যান্সে (এখনই, @ গ্যাবের মন্তব্য পড়ার পরে) পারফরম্যান্সে নাটকীয় উন্নতি করেছি। বটমলাইন: এখন থেকে আমি কেবলমাত্র একটি লক ব্লকের ভিতরে ভেরিয়েবল অ্যাক্সেস (সাধারণত একটি লাইন) রেখে দেব, "টাইম লক ইন টাইপ" sort এটা কি কোন মানে আছে?
হেলটনবাইকার

2
@ হেল্টনবিকার অবশ্যই এটি বোধগম্য হয়। এটি আর্কিটেকচারাল নীতিও হওয়া উচিত, আপনার যতটা সম্ভব সংক্ষিপ্ত, সহজ এবং দ্রুত লক তৈরি করার কথা। কেবলমাত্র প্রয়োজনীয় ডেটা যা সিঙ্ক্রোনাইজ করা দরকার। সার্ভার বাক্সগুলিতে, আপনাকে লকটির সংকর প্রকৃতিও বিবেচনা করা উচিত। আপনার কোডটির জন্য সমালোচনা না করলেও বিতর্ক হ'ল লকটির সংকর প্রকৃতির জন্য ধন্যবাদ, যদি লকটি অন্য কারও কাছে ধরে থাকে তবে প্রতিটি অ্যাক্সেসের সময় কোরগুলি স্পিন করে দেয়। আপনার থ্রেড স্থগিত হওয়ার আগে আপনি কিছু সময়ের জন্য সার্ভারের অন্যান্য পরিষেবাদি থেকে কিছু সিপিইউ সংস্থান কার্যকরভাবে গ্রাস করছেন।
ipavlu

উত্তর:


86

এখানে একটি নিবন্ধ যা ব্যয় হয় is সংক্ষিপ্ত উত্তর 50ns।


39
সংক্ষিপ্ততর উত্তর: অন্যান্য থ্রেড যদি লক ধরে থাকে তবে 50ns + সময় অপেক্ষা করতে ব্যয় করেছে।
হারমান

4
যত বেশি থ্রেড লক প্রবেশ করছে এবং ছেড়ে যাচ্ছে তত বেশি ব্যয়বহুল। থ্রেডের সংখ্যার সাথে ব্যয়টি তাত্পর্যপূর্ণভাবে প্রসারিত হয়
আর্সেন জহরে

16
কিছু প্রসঙ্গ: 3Ghz x86 এ দুটি সংখ্যা বিভক্ত করতে প্রায় 10ns সময় লাগে (নির্দেশটি আনতে / ডিকোড করতে সময় লাগে না সহ) ; এবং একটি রেজিস্টারে (অ-ক্যাশেড) মেমরি থেকে একক ভেরিয়েবল লোড করতে প্রায় 40ns সময় লাগে। সুতরাং 50ns উন্মত্তভাবে, অন্ধভাবে দ্রুত - আপনার lockএকটি ভেরিয়েবল ব্যবহারের ব্যয় সম্পর্কে যে পরিমাণ চিন্তা করতে হবে তার চেয়ে বেশি কোনও ব্যবহারের ব্যয় নিয়ে আপনার চিন্তা করা উচিত নয় ।
ব্লুরাজা - ড্যানি পিফ্লুঘিওফ্ট

3
এছাড়াও, এই প্রশ্নটি যখন জিজ্ঞাসা করা হয়েছিল তখন সেই নিবন্ধটি পুরানো ছিল।
ওটিস

3
সত্যই দুর্দান্ত মেট্রিক, "প্রায় কোনও দাম নেই", ভুল উল্লেখ না করে। আপনারা সবাই বিবেচনা করবেন না, এটি কেবল সংক্ষিপ্ত এবং দ্রুত এবং কেবলমাত্র একটি থ্রেডে কোনও বিতর্ক না থাকলে কেবল। অনেক ক্ষেত্রে, আপনি সমস্ত কিছু প্রয়োজন নেই। দ্বিতীয় ইস্যু, লকটি লক নয়, তবে হাইব্রিড লকটি এটি সিএলআরের অভ্যন্তরে সনাক্ত করে যে লকটি পারমাণবিক ক্রিয়াকলাপের ভিত্তিতে কারও দ্বারা রাখা হয় না এবং এই ক্ষেত্রে এটি অপারেটিং সিস্টেম কোরকে কলগুলি এড়িয়ে যায়, এটি ভিন্ন রিং যা এগুলি দ্বারা পরিমাপ করা হয় না is পরীক্ষা। 25ns থেকে 50ns হিসাবে কী পরিমাপ করা হয় তা হ'ল অ্যাপ্লিকেশন স্তরের ইন্টারলকড নির্দেশাবলী কোড যদি লক না নেওয়া হয়
আইপাবলু

50

প্রযুক্তিগত উত্তরটি হ'ল এটি পরিমাণ নির্ধারণ করা অসম্ভব, এটি সিপিইউ মেমরির লিখিত-ব্যাক বাফারগুলির অবস্থার উপর নির্ভর করে এবং প্রিফেটর যে পরিমাণ ডেটা সংগ্রহ করেছিলেন তা ফেলে দেওয়া এবং পুনরায় পড়তে হবে। যা উভয়ই অত্যন্ত অ-সংঘবদ্ধ are আমি খামের পিছনের দিকে 150 সিপিইউ চক্র ব্যবহার করি যা বড় হতাশাকে এড়িয়ে চলে।

ব্যবহারিক উত্তরটি হ'ল আপনি যদি কোনও লক এড়াতে পারবেন বলে মনে করেন তখন আপনার কোডটি ডিবাগ করার সময় আপনি যে পরিমাণ বার্ন পোড়াবেন তা তুলনায় এটি সস্তা।

একটি হার্ড নম্বর পেতে আপনাকে পরিমাপ করতে হবে। ভিজ্যুয়াল স্টুডিওতে একটি এক্সটেনশান হিসাবে উপলব্ধ একটি চটজলদি একাধিক বিশ্লেষক আছে


1
আসলে না, এটি পরিমাণযুক্ত এবং পরিমাপ করা যেতে পারে। কোডের চারপাশে এই লকগুলি লেখার মতো সহজ নয়, তারপরে এটি উল্লেখ করে যে এটি সমস্ত মাত্র 50ns, লকটিতে একক থ্রেডেড অ্যাক্সেসে পরিমাপক একটি পৌরাণিক কাহিনী।
ipavlu

8
"মনে হয় আপনি কোনও লক এড়িয়ে যেতে পারেন" ... আমার মনে হয় এই প্রশ্নটি পড়ে যখন প্রচুর লোকেরা সেখানে থাকে ...
স্নুপ

30

আরও পড়া:

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

https://www.codeproject.com/Articles/1236238/Unified-Concurrency-I-Itrration https://www.codeproject.com/Articles/1237518/Unified-Concurrency-II-benchmarking- ধারণাবাদ https: // www। codeproject.com/Articles/1242156/Unified-Concurrency-III-cross-benchmarking

আসল উত্তর:

ওহে প্রিয়!

দেখে মনে হচ্ছে উত্তর উত্তর হিসাবে সহজাত ভুল হিসাবে চিহ্নিত হয়েছে এখানে সঠিক উত্তর! আমি উত্তরটির লেখককে শ্রদ্ধার সাথে জিজ্ঞাসা করতে চাই, লিঙ্কিত নিবন্ধটি শেষ পর্যন্ত পড়তে। প্রবন্ধ

২০০৩ নিবন্ধের নিবন্ধটির লেখক কেবলমাত্র ডুয়াল কোর মেশিনে পরিমাপ করছিলেন এবং প্রথম পরিমাপের ক্ষেত্রে তিনি কেবল একটি একক থ্রেডের সাথে লকিং পরিমাপ করেছিলেন এবং লক অ্যাক্সেসের জন্য প্রায় 50ns ফলাফল ছিল।

এটি সমবর্তী পরিবেশে একটি লক সম্পর্কে কিছুই বলে না। সুতরাং আমাদের নিবন্ধটি পড়া চালিয়ে যেতে হবে এবং দ্বিতীয়ার্ধে, লেখক দুটি এবং তিনটি থ্রেডের সাথে লকিংয়ের পরিস্থিতিটি পরিমাপ করছিলেন যা আজকের প্রসেসরের সামঞ্জস্যের স্তরের কাছাকাছি যায়।

সুতরাং লেখক বলেছেন, দ্বৈত কোরের দুটি থ্রেড সহ, লকগুলির দাম 120ns এবং 3 টি থ্রেড সহ এটি 180ns এ যায়। সুতরাং এটি একই সাথে লকটিতে অ্যাক্সেসের সংখ্যার উপর সুস্পষ্টভাবে নির্ভরশীল বলে মনে হচ্ছে।

সুতরাং এটি সহজ, এটি 50 এনএস নয় যদি না এটি একটি একক থ্রেড হয়, যেখানে লকটি অকেজো হয়ে যায়।

বিবেচনার জন্য আর একটি বিষয় এটি গড় সময় হিসাবে পরিমাপ করা হয় !

যদি পুনরাবৃত্তির সময়টি পরিমাপ করা হয় তবে 1 মিমি থেকে শুরু করে 20 মিমি এর মধ্যেও বেশ কয়েকবার সময় আসতে পারে কারণ কেবল সংখ্যাগরিষ্ঠটি দ্রুত ছিল তবে কয়েকটি থ্রেড প্রসেসরের সময় অপেক্ষা করতে থাকবে এবং এমনকি মিলিসেকেন্ডে দীর্ঘ বিলম্বও ঘটবে।

এটি যে কোনও ধরণের অ্যাপ্লিকেশনের জন্য খারাপ সংবাদ, যার জন্য উচ্চ থ্রুপুট, কম বিলম্বের প্রয়োজন।

এবং বিবেচনার জন্য শেষ ইস্যুটি হ'ল লকের অভ্যন্তরে ধীর গতিতে চলতে পারে এবং প্রায়শই এটি ঘটে। কোডটির ব্লকটি লকের অভ্যন্তরে যত দীর্ঘায়িত হবে তত যুক্তি তত বেশি এবং আকাশে উঁচুতে বিলম্ব হবে।

দয়া করে বিবেচনা করুন, ২০০৩ সাল থেকে ইতিমধ্যে এক দশকেরও বেশি সময় পেরিয়ে গেছে, এটি পুরোপুরি একযোগে চালানোর জন্য ডিজাইন করা প্রসেসরের কয়েকটি প্রজন্ম এবং লকিং তাদের কর্মক্ষমতাকে যথেষ্ট ক্ষতি করছে।


1
স্পষ্ট করার জন্য, নিবন্ধটি বলছে না যে লকটির কার্যকারিতা অ্যাপ্লিকেশনটিতে থাকা থ্রেডের সংখ্যার সাথে হ্রাস পায়; লকটি নিয়ে লড়াইয়ের থ্রেডের সংখ্যার সাথে কর্মক্ষমতা হ্রাস পায়। (উপরের উত্তরে এটি নিহিত, তবে স্পষ্টভাবে বলা হয়নি)
গজবেরি

আমি মনে করি আপনি এটি বোঝাতে চাইছেন: "সুতরাং এটি একত্রে অ্যাক্সেস করা থ্রেডের সংখ্যার উপর স্পষ্টভাবে নির্ভরশীল বলে মনে হচ্ছে এবং আরও খারাপ।" হ্যাঁ, শব্দটি আরও ভাল হতে পারে। থ্রেডগুলি একই সাথে লকটিতে অ্যাক্সেস করা হিসাবে আমি "একযোগে অ্যাক্সেস করা" বোঝাতে চাইছিলাম, সুতরাং বিতর্ক তৈরি করা হয়েছিল।
ipavlu

20

পারফরম্যান্স সম্পর্কে এটি আপনার প্রশ্নের জবাব দেয় না, তবে আমি বলতে পারি যে .NET ফ্রেমওয়ার্ক এমন একটি Interlocked.Addপদ্ধতি প্রস্তাব করে যা আপনাকে অন্য কোনও বস্তুতে ম্যানুয়ালি লক না করেই amountআপনার doneসদস্যকে যুক্ত করতে দেয় allow


1
হ্যাঁ, এটি সম্ভবত সেরা উত্তর। তবে প্রধানত সংক্ষিপ্ত এবং ক্লিনার কোডের কারণে। গতির পার্থক্য লক্ষণীয় হওয়ার সম্ভাবনা নেই।
হেন্ক হলটারম্যান

এই উত্তরের জন্য ধন্যবাদ। আমি তালা দিয়ে আরও জিনিস করছি যুক্ত ইনট অনেকের মধ্যে একটি। পরামর্শটি পছন্দ করুন, এখন থেকে এটি ব্যবহার করবে।
কিস সি বাকার

লক-ফ্রি কোড সম্ভাব্য তত দ্রুত হওয়া সত্ত্বেও লকগুলি ডান পেতে অনেক বেশি সহজ। ইন্টারলকড.একটি নিজস্ব সংযোজনে + = সমান সমন্বয় না করে একই সমস্যা রয়েছে with
হ্যাঙ্গার

10

lock (মনিটর.এন্টার / প্রস্থান) ওয়েটহ্যান্ডেল বা মিটেক্সের মতো বিকল্পগুলির তুলনায় খুব সস্তা, সস্তা।

তবে কী যদি এটি (কিছুটা) ধীর হয়ে যায়, আপনি কি ভুল ফলাফল সহ একটি দ্রুত প্রোগ্রাম করবেন?


5
হাহাহা ... আমি দ্রুত প্রোগ্রাম এবং ভাল ফলাফলের জন্য যাচ্ছিলাম।
কিস সি বাকার

@ হেন্ক-হোল্টারম্যান আপনার বক্তব্যগুলির সাথে একাধিক সমস্যা রয়েছে: প্রথম যেমন এই প্রশ্ন এবং উত্তরগুলি পরিষ্কারভাবে দেখিয়েছে, সামগ্রিক কর্মক্ষমতাতে লকের প্রভাব সম্পর্কে কম ধারণা রয়েছে, এমনকি লোকেরা 50ns সম্পর্কে মিথকথা উল্লেখ করে যা শুধুমাত্র একক থ্রেডযুক্ত পরিবেশের সাথে প্রযোজ্য। দ্বিতীয় আপনার বিবৃতিটি এখানে এবং বছরের পর বছর ধরে থাকবে এবং প্রসেসরের কোরগুলিতে বেড়েছে, তবে কোরগুলির গতি এত বেশি হয় না * ** থ্রড ** অ্যাপ্লিকেশনগুলি সময়ের সাথে সাথে আরও জটিল হয়ে যায় এবং তারপরে এটি স্তর স্তর হয়ে থাকে অনেকগুলি কোরের পরিবেশে লকিং এবং সংখ্যাটি বাড়ছে, 2,4,8,10,20,16,32
ipavlu

আমার স্বাভাবিক পদ্ধতিটি হ'ল যতটা সম্ভব স্বল্প পারস্পরিক মিথস্ক্রিয়া নিয়ে আলগাভাবে যুগল উপায়ে সিঙ্ক্রোনাইজেশন তৈরি করা। এটি লক-ফ্রি ডেটা স্ট্রাকচারগুলিতে খুব দ্রুত চলে যায়। আমি স্পিনলকের চারপাশে আমার কোডের মোড়কের জন্য তৈরি করেছি উন্নয়নকে সহজতর করার জন্য এবং টিপিএলের বিশেষ সমবর্তী সংগ্রহ রয়েছে, তখনও আমি তালিকাটির সাথে আমার নিজের স্পিন লক করা সংগ্রহগুলি তৈরি করেছি, অ্যারে, অভিধান এবং সারি, কারণ আমার আরও কিছুটা নিয়ন্ত্রণ প্রয়োজন এবং কখনও কখনও কিছু কোডের অধীনে চলতে থাকে needed spinlock। আমি আপনাকে বলতে পারি, এটি সম্ভব এবং টিপিএল সংগ্রহগুলি করতে পারে না এবং দুর্দান্ত পারফরম্যান্স / থ্রুপুট লাভের সাথে একাধিক পরিস্থিতি সমাধান করার অনুমতি দেয়।
ipavlu

7

কোনও লকবিহীন বিকল্পের তুলনায় টাইট লুপে লকের জন্য ব্যয়টি বিশাল। আপনি অনেকবার লুপ বহন করতে পারেন এবং এখনও একটি লকের চেয়ে আরও দক্ষ হতে পারেন। এজন্য লক ফ্রি সারিতে এত দক্ষ।

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LockPerformanceConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            var stopwatch = new Stopwatch();
            const int LoopCount = (int) (100 * 1e6);
            int counter = 0;

            for (int repetition = 0; repetition < 5; repetition++)
            {
                stopwatch.Reset();
                stopwatch.Start();
                for (int i = 0; i < LoopCount; i++)
                    lock (stopwatch)
                        counter = i;
                stopwatch.Stop();
                Console.WriteLine("With lock: {0}", stopwatch.ElapsedMilliseconds);

                stopwatch.Reset();
                stopwatch.Start();
                for (int i = 0; i < LoopCount; i++)
                    counter = i;
                stopwatch.Stop();
                Console.WriteLine("Without lock: {0}", stopwatch.ElapsedMilliseconds);
            }

            Console.ReadKey();
        }
    }
}

আউটপুট:

With lock: 2013
Without lock: 211
With lock: 2002
Without lock: 210
With lock: 1989
Without lock: 210
With lock: 1987
Without lock: 207
With lock: 1988
Without lock: 208

4
এটি একটি খারাপ উদাহরণ হতে পারে কারণ আপনার লুপটি সত্যই কিছু করে না, একক ভেরিয়েবল অ্যাসাইনমেন্ট ছাড়াও কোনও লক কমপক্ষে 2 ফাংশন কল। এছাড়াও, 20 লন প্রতি আপনি যে লক পাচ্ছেন তা খুব খারাপ নয়।
জার শারদান

5

"ব্যয়" সংজ্ঞায়নের কয়েকটি ভিন্ন উপায় রয়েছে। লকটি গ্রহণ এবং ছেড়ে দেওয়ার আসল ওভারহেড রয়েছে; জ্যাক যেমন লিখেছেন, এটি লক্ষণীয় নয় যদি না এই অপারেশনটি কয়েক মিলিয়ন বার সম্পাদিত হয়।

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

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.