PDA

View Full Version : آموزش: آشنایی با Parallel LINQ یا PLINQ



tooraj_azizi_1035
دوشنبه 22 خرداد 1391, 13:02 عصر
سلام

در سال 2010 مایکروسافت قابلیت اجرای موازی رو به LINQ اضافه کرد.
Parallel LINQ (PLINQ) نسخه موازی LINQ to Objects است.

PLINQ مانند LINQ به شکل تعویقی اجر می شود (Deffered Execution) یعنی تا زمانی که حاصل Query شمارش نشود (Enumerate) اجرا نمی شود. تفاوت اصلی در این است که PLINQ تلاش می کند تا از تمام هسته های CPU استفاده کند.
PLINQ این کار را با پارتیشن کردن منبع داده ها به چند قسمت که سگمنت نامیده می شود و سپس اجرای کوئری توسط نخ های جداگانه روی سگمنت های جداگانه انجام میدهد.
PLINQ با فراخوانی متد AsParallel(). منبع داده ها فراخوانی می شود. با این وجود موازی سازی پیچیدگی های خاص خودش را دارد و هر Query الزاماً با موازی سازی سریعتر اجرا نخواهد شد. در حقیقت موازی کردن برخی Query ها می تواند نتیجه عکس بدهد و سرعت را کاهش دهد.


var source = Enumerable.Range(1, 10000);


// Opt-in to PLINQ with AsParallel
var evenNums = from num in source.AsParallel()
where Compute(num) > 0
select num;


PLINQ در اجرا محافظه کارانه عمل می کند. در زمان اجرا PLINQ کوئری را تحلیل می کند تا از ارزش موازی کردن آن مطلع شود. اگر کوئری از موازی سازی سود ببرد PLINQ منبع داده ها را قسمت بندی کرده و توسط چندین نخ کوئری را همزمان روی بخش های مختلف داده ها اجرا می کند.

در صورتی که PLINQ در حالت انتخاب میان یک الگوریتم موازی سازی پرهزینه و یک الگوریتم سریال نه چندان پر هزینه قرار بگیرد PLINQ گزینه اجرای سریال را انتخاب می کند. گر چه شما می توانید PLINQ را با متد WithExecutionMode مجبود کنید که کوئری را موازی اجرا کند.

PLINQ به طور پیش فرض از همه پردازنده های ماشین میزبان تا حداکثر 64 پردازنده استفاده می کند اما شما می توانید PLINQ را وادار کنید تا حداکثر از تعداد خاصی از پردازنده ها استفاده نماید با استفاده از متد WithDegreeOfParallelism.


var query = from item in source.AsParallel().WithDegreeOfParallelism(2)
where Compute(item) > 42
select item;


در برخی از کوئری های ترتیب عناصر خروجی باید با ترتیب همان عناصر در منبع داده ها برابری کند.
PLINQ متد AsOrdered را به این منظور فراهم کرده است.


evenNums = from num in numbers.AsParallel().AsOrdered() where num % 2 == 0 select num;


بعدها تکمیل تر خواهم گفت.