国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

ParallelProgramming-Paralle.For&&ForEach

2019-11-14 13:48:05
字體:
來源:轉載
供稿:網友

本文主要介紹Parallel.For以及Parallel.ForEach。Parallel.For是普通步長為1的for循環的并行代替方案。Parallel.ForEach是以集合為基準進行循環的foreach的并行代替方案。主要以下內容:

  1. 使用例子
  2. 如何退出并行循環
  3. Break、Stop詳細介紹
  4. Partitioner

一、Parallel.For

1.1 使用例子

 class ParallelFor    {        PRivate void Action(int index)        {            Console.WriteLine(index);            Thread.Sleep(1000);        }        public void ParallelAction()        {            Parallel.For(0, 10, (i) => Action(i));        }    } class Program    {        static void Main(string[] args)        {            var stopwatch = Stopwatch.StartNew();            stopwatch.Start();            new ParallelFor().ParallelAction();            Console.WriteLine(stopwatch.ElapsedMilliseconds);            Console.Read();        }    }

1.2 運行截圖

時間有很大的提升。

二、跳出循環:Break vs Stop

串行執行的for可以使用break/Stop關鍵字直接退出循環。Parallel.For可以通過loopState進行退出或者停止循環。

 class ParallelFor    {        private void Action(int index)        {            Console.WriteLine(index);            Thread.Sleep(1000);        }        public void ParallelAction()        {            Parallel.For(0, 10, (i, loopState) =>            {                if (i == 8)                {                    loopState.Break();//loopState.Stop()                }                Action(i);            });        }    }

LoopState是循環體的第一個參數(可選),第一個是i。

三、 Break和Stop的區別

當Break執行時,小于當前的index(i)的操作都會保證執行完成,大于當前index的迭代不再開始(不是不再執行)-》已經開始的還是會繼續執行。

Break indicates that no iterations after the current iteration should be run. It effectively cancels any additional iterations of the loop. However, it does not stop any iterations that have already begun execution. 

進一步說明:當index為8的循環開始執行時,index為1,2,3的循環不一定已經開始了。所以當Break執行后(index為8),會保證沒有執行的1,2,3執行完畢

比如上面的例子i==8時,進行break,上面的代碼執行截圖:

0-7保證執行,8也打印出來了(有可能還會有10,9),是因為index8對應的循環在break之前已經開始了。

當Stop執行時,Parallel會用最快的速度結束循環,如果小于當前執行stop的index對應的循環操作還沒有開始,則不會執行這些沒有開始的。所以Stop比Break能夠更加快速的結束迭代。

Calling the Stop method indicates that any iterations of the loop that have not yet started need not be run. It effectively cancels any additional iterations of the loop. However, it does not stop any iterations that have already begun execution.

Calling the Stop method causes the IsStopped property to return true for any iteration of the loop that is still executing. This is particularly useful for long-running iterations, which can check the IsStopped property and exit early if its value is true.

Stop is typically employed in search-based algorithms, where once a result is found, no other iterations need be executed.

Break和Stop不能同時使用,會有異常拋出。

四、Continue功能。

Parallel.For是沒有Continue關鍵字的,簡單的使用Return即可完成Continue的功能。

 public void ParallelAction(){            Parallel.For(0, 10, (i) =>            {                if (i == 10)                {                    return;                }                Action(i);            });}

五、ParallelOptions

Parallel.For通用有ParallelOptions這個屬性,通過這個可以指定CancellationSourceToken和MaxDegreeOfParallelism(最大并發數)

 public void ParallelAction() {            var cts = new CancellationTokenSource();            var option = new ParallelOptions()            {                CancellationToken = cts.Token,                MaxDegreeOfParallelism = 5            };            Parallel.For(0, 10, option, (i) =>            {                if (cts.Token.IsCancellationRequested)                {                    return;                }                Action(i);            }); }

 六、Partitioner

本文一直在講解Parallel.For上面的操作對于Parallel.ForEach都是通用的。但是Parallel.ForEach有個特殊功能。Partitioner。

6.1 例子

class ParallelForEach{        public void ParallelAction()        {            int[] items = new int[100000];            Parallel.ForEach(Partitioner.Create(0, 100000, 50000), (range) =>            {                Console.WriteLine("IN Parallel");                for (var i = range.Item1; i < range.Item2; i++)                {                    items[i] = i;                }            });        }}

上面代碼的把1000000次分成兩個50000進行,這兩個50000之間是并行執行的,但是在每個50000(range)是串行自己執行的。上面程序會打印出兩"IN Parallel"。

6.2說明

為什么要使用Partitioner?使用并行開發有兩大開銷,一是線程調度,二是調度代理方法,如果循環體本身開銷很小,大量使用線程會得不償失:調度本身的開銷大于使用并行帶來的性能提升。上面的例子可以看出,使用Partitioner減少了并行的次數,增大了循環體的體積。達到了并行和調度開銷的協調。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 收藏| 邳州市| 汪清县| 金阳县| 绥滨县| 泗水县| 麦盖提县| 罗山县| 永泰县| 桦川县| 青田县| 石首市| 舒城县| 贵阳市| 浏阳市| 佛坪县| 吕梁市| 屯留县| 枣庄市| 巴青县| 沿河| 广东省| 称多县| 丁青县| 资阳市| 咸宁市| 桓台县| 喀什市| 达日县| 德阳市| 海城市| 江陵县| 嘉禾县| 巨鹿县| 米脂县| 五指山市| 洛川县| 广东省| 苍梧县| 福建省| 呼图壁县|