এই কোড দেওয়া:
var arrayStrings = new string[1000];
Parallel.ForEach<string>(arrayStrings, someString =>
{
DoSomething(someString);
});
সমস্ত 1000 থ্রেড প্রায় একসাথে ছড়িয়ে পড়বে?
এই কোড দেওয়া:
var arrayStrings = new string[1000];
Parallel.ForEach<string>(arrayStrings, someString =>
{
DoSomething(someString);
});
সমস্ত 1000 থ্রেড প্রায় একসাথে ছড়িয়ে পড়বে?
উত্তর:
না, এটি 1000 থ্রেড শুরু করবে না - হ্যাঁ, এটি কতগুলি থ্রেড ব্যবহার করবে তা সীমাবদ্ধ করবে। আপনার শারীরিকভাবে কতজন রয়েছে এবং কতজন ইতিমধ্যে ব্যস্ত রয়েছেন তার উপর ভিত্তি করে সমান্তরাল এক্সটেনশনগুলি উপযুক্ত সংখ্যক কোর ব্যবহার করে । এটি প্রতিটি কোরের জন্য কাজ বরাদ্দ করে এবং তারপরে প্রতিটি থ্রেডকে দক্ষতার সাথে নিজস্ব কাতারে প্রক্রিয়া করতে দেয় এবং ওয়ার্ক স্টিলিং নামক একটি প্রযুক্তি ব্যবহার করে তবে যখন সত্যিই প্রয়োজন হয় তখন কোনও ব্যয়বহুল ক্রস-থ্রেড অ্যাক্সেস করতে হবে।
কটাক্ষপাত আছে PFX টিম ব্লগ জন্য লোড এবং কিভাবে এটা কাজ বরাদ্দ সম্পর্কে তথ্য অন্যান্য বিষয় সব ধরণের।
মনে রাখবেন যে কিছু ক্ষেত্রে আপনি যে সমান্তরালতা চান সেটিও ডিগ্রি নির্দিষ্ট করতে পারেন।
একটি একক কোর মেশিনে ... সমান্তরাল.একটি সংগ্রহের প্রতিটি পার্টিশন (অংশ) এটি বিভিন্ন সংখ্যক থ্রেডের মধ্যে কাজ করে তবে এই সংখ্যাটি একটি অ্যালগরিদমের ভিত্তিতে গণনা করা হয় যা অ্যাকাউন্টে গ্রহণ করে এবং নিয়মিতভাবে কাজটি পর্যবেক্ষণ করে প্রদর্শিত হয় থ্রেডগুলি এটি ফরইচে বরাদ্দ করা হয়। সুতরাং যদি ফোআরচের দেহের অংশটি দীর্ঘ চলমান আইও-বাউন্ড / ব্লকিং ফাংশনগুলিতে কল করে যা থ্রেডটি প্রায় অপেক্ষায় ছেড়ে যায়, তবে অ্যালগরিদম আরও থ্রেড উত্পন্ন করবে এবং তাদের মধ্যে সংগ্রহটি পুনরায় ভাগ করবে । যদি থ্রেডগুলি দ্রুত সম্পন্ন হয় এবং উদাহরণস্বরূপ আইও থ্রেডগুলিতে অবরুদ্ধ না হয় যেমন কিছু নম্বর গণনা করা,অ্যালগরিদম থ্রেডের সংখ্যাটিকে একটি বিন্দুতে বাড়িয়ে তুলবে (বা সত্যই নিচে) যেখানে অ্যালগরিদম থ্রুপুটটির জন্য সর্বোত্তম বিবেচনা করে (প্রতিটি পুনরাবৃত্তির গড় সমাপ্তির সময়) ।
মূলত সমস্ত বিভিন্ন সমান্তরাল গ্রন্থাগার ফাংশনের পিছনে থ্রেড পুলটি ব্যবহারের জন্য সর্বোত্তম সংখ্যক থ্রেড তৈরি করবে। শারীরিক প্রসেসরের কোরগুলির সংখ্যা সমীকরণের একমাত্র অংশ গঠন করে। মূল সংখ্যা এবং প্রসারিত থ্রেডের সংখ্যার মধ্যে একের সাথে সহজ সম্পর্ক নেই।
থ্রেডগুলি সিঙ্ক্রোনাইজ করার জন্য বাতিলকরণ এবং পরিচালনা করার আশেপাশে ডকুমেন্টেশনগুলি খুব সহায়ক হিসাবে খুঁজে পাচ্ছি না। আশা করি এমএসডিএন তে এমএস আরও ভাল উদাহরণ সরবরাহ করতে পারে।
ভুলে যাবেন না, একাধিক থ্রেডে চালনার জন্য বডি কোড অবশ্যই লিখতে হবে, সমস্ত সাধারণ থ্রেড সুরক্ষা বিবেচনার সাথে ফ্রেমওয়ার্কটি সেই ফ্যাক্টরটিকে বিমূর্ত করে না ... এখনও।
এটি প্রসেসর / কোরগুলির সংখ্যার ভিত্তিতে থ্রেডগুলির সর্বোত্তম সংখ্যার কাজ করে। এগুলি একসাথে ছড়িয়ে পড়বে না।
সমান্তরালটি দেখুন ? প্রতিবারের জন্য একটি টাস্ক ব্যবহার করুন? "মানসিক মডেল" ব্যবহার করার জন্য একটি ধারণার জন্য। তবে লেখক উল্লেখ করেছেন যে "দিনের শেষে, এটি মনে রাখা গুরুত্বপূর্ণ যে বাস্তবায়নের বিশদ যে কোনও সময় পরিবর্তন হতে পারে।"
দুর্দান্ত প্রশ্ন। আপনার উদাহরণস্বরূপ, কোয়াড কোর প্রসেসরের তুলনায় সমান্তরালকরণের স্তরটি খুব কম, তবে কিছুটা অপেক্ষার সাথে সমান্তরালকরণের স্তরটি বেশ উচ্চতর হতে পারে।
// Max concurrency: 5
[Test]
public void Memory_Operations()
{
ConcurrentBag<int> monitor = new ConcurrentBag<int>();
ConcurrentBag<int> monitorOut = new ConcurrentBag<int>();
var arrayStrings = new string[1000];
Parallel.ForEach<string>(arrayStrings, someString =>
{
monitor.Add(monitor.Count);
monitor.TryTake(out int result);
monitorOut.Add(result);
});
Console.WriteLine("Max concurrency: " + monitorOut.OrderByDescending(x => x).First());
}
এইচটিটিপি অনুরোধের অনুকরণে ওয়েটিং অপারেশন যুক্ত করা হলে কী হবে তা দেখুন।
// Max concurrency: 34
[Test]
public void Waiting_Operations()
{
ConcurrentBag<int> monitor = new ConcurrentBag<int>();
ConcurrentBag<int> monitorOut = new ConcurrentBag<int>();
var arrayStrings = new string[1000];
Parallel.ForEach<string>(arrayStrings, someString =>
{
monitor.Add(monitor.Count);
System.Threading.Thread.Sleep(1000);
monitor.TryTake(out int result);
monitorOut.Add(result);
});
Console.WriteLine("Max concurrency: " + monitorOut.OrderByDescending(x => x).First());
}
আমি এখনও কোনও পরিবর্তন করি নি এবং সমঝোতা / সমান্তরালনের স্তরটি ক্রমহ্রাসে বেড়েছে। কনকুরেন্সির সাথে এর সীমা বাড়তে পারে ParallelOptions.MaxDegreeOfParallelism
।
// Max concurrency: 43
[Test]
public void Test()
{
ConcurrentBag<int> monitor = new ConcurrentBag<int>();
ConcurrentBag<int> monitorOut = new ConcurrentBag<int>();
var arrayStrings = new string[1000];
var options = new ParallelOptions {MaxDegreeOfParallelism = int.MaxValue};
Parallel.ForEach<string>(arrayStrings, options, someString =>
{
monitor.Add(monitor.Count);
System.Threading.Thread.Sleep(1000);
monitor.TryTake(out int result);
monitorOut.Add(result);
});
Console.WriteLine("Max concurrency: " + monitorOut.OrderByDescending(x => x).First());
}
// Max concurrency: 391
[Test]
public void Test()
{
ConcurrentBag<int> monitor = new ConcurrentBag<int>();
ConcurrentBag<int> monitorOut = new ConcurrentBag<int>();
var arrayStrings = new string[1000];
var options = new ParallelOptions {MaxDegreeOfParallelism = int.MaxValue};
Parallel.ForEach<string>(arrayStrings, options, someString =>
{
monitor.Add(monitor.Count);
System.Threading.Thread.Sleep(100000);
monitor.TryTake(out int result);
monitorOut.Add(result);
});
Console.WriteLine("Max concurrency: " + monitorOut.OrderByDescending(x => x).First());
}
আমি সেটিংটি সুপারিশ করছি ParallelOptions.MaxDegreeOfParallelism
। এটি অগত্যা ব্যবহারে থ্রেডের সংখ্যা বাড়িয়ে দেবে না, তবে এটি নিশ্চিত করবে যে আপনি কেবল একটি বুদ্ধিমান থ্রেড শুরু করেছেন, এটি আপনার উদ্বেগ বলে মনে হচ্ছে।
শেষ পর্যন্ত আপনার প্রশ্নের উত্তর দেওয়ার জন্য, না আপনি একবারে সমস্ত থ্রেড শুরু করতে পারবেন না। সমান্তরাল ব্যবহার করুন.আপনি সমান্তরালভাবে পুরোপুরি অনুরোধ করতে চাইছেন যেমন উদ্বোধন করুন দৌড়ের অবস্থাগুলির পরীক্ষা করা।
// 636462943623363344
// 636462943623363344
// 636462943623363344
// 636462943623363344
// 636462943623363344
// 636462943623368346
// 636462943623368346
// 636462943623373351
// 636462943623393364
// 636462943623393364
[Test]
public void Test()
{
ConcurrentBag<string> monitor = new ConcurrentBag<string>();
ConcurrentBag<string> monitorOut = new ConcurrentBag<string>();
var arrayStrings = new string[1000];
var options = new ParallelOptions {MaxDegreeOfParallelism = int.MaxValue};
Parallel.ForEach<string>(arrayStrings, options, someString =>
{
monitor.Add(DateTime.UtcNow.Ticks.ToString());
monitor.TryTake(out string result);
monitorOut.Add(result);
});
var startTimes = monitorOut.OrderBy(x => x.ToString()).ToList();
Console.WriteLine(string.Join(Environment.NewLine, startTimes.Take(10)));
}