• 并行循环


    上次我们讲到了集合。说到集合,那往往少不了循环。今天我们说下什么是并行循环

    Parallel.For,Paraller.Foreach 

    (System.Threading.Tasks)

    相信大家对此都不陌生。

     long sum = 0;
                Parallel.For(0, MaxValue, (i) =>
                {
                    Interlocked.Add(ref sum, (long)Math.Sqrt(i));
                    values.Add(i);
                });

    也可以Paraller.Foreach.

    中断循环:

    如果需要中断循环,可以给循环的委托传入一个ParallelLoopState对象,中止循环。有两个方法。

    Break,Stop;区别是什么呢?

    1:Break---告诉循环不要执行大于当前迭代次数的任何迭代。啥意思呢。就是大于i 的都会停止运行,小于i的依然会执行。注意:可能会有多个循环迭代发起Break调用,要看代码逻辑了。

    2:Stop:----停止任何迭代。

     问题调整

     ~对了。在使用并行循环的时候,要确保每次迭代的工作量要明显大于同步共享状态的开销。如果你把循环的时间都耗在阻塞共享的循环变量上,那并行执行也就没意义了。所以每次迭代都进行局部访问,

    ~并行循环还有另一个问题,就是委托。每次都会生成一个委托,如果每次迭代完成的工作还不如生成委托的开销大。那就是杀鸡用牛刀。大材小用。

    说下委托的开销吧。委托的开销分为两种:构造开销和调用开销,调用和普通方法调用差不多。构造开销就很大。你应该只做一次构造,并把对象缓存起来。把委托定义在循环外。

    上面的问题怎么解决呢?

    用Partitioner类,它会把需要的迭代的区间分拆存入Tuple对象种。

    public static void Main()
      {
        Stopwatch watch=new Stopwatch();
        const int MaxValue=10000000;
        long sum=0;
    
        //普通循环
        watch.Restart();
        sum=0;
        Parallel.For(0,MaxValue,(i)=>{
          Interlocked.Add(ref sum,(long)Math.Sqrt(i));
        });
        watch.Stop();
        Console.WriteLine("Parallel.For:{0}",watch.Elapsed);
        
        //分区的For循环
        var partitioner=Partitioner.Create(0,MaxValue);
        watch.Restart();
        sum=0;
        Parallel.ForEach(partitioner,(range)=>{
          long partialSum=0;
          for(int i=range.Item1;i<range.Item2;i++)
          {
            partialSum+=(long)Math.Sqrt(i);
          }
          Interlocked.Add(ref sum,partialSum);
        });
        watch.Stop();
        Console.WriteLine("Partitioned Parallel.For:{0}",watch.Elapsed);
      }

     我的电脑上执行的结果。

    上面分区规则是静态的,只要迭代区间划分完毕,每个区间都运行一个委托。其中有一个提前完成,也不会尝试重新分区。

  • 相关阅读:
    回调函数中调用类中的非静态成员变量或非静态成员函数
    [NewCoder]复杂链表的复制
    C++对象模型--总结
    chunk writer 中需要对抛错的交易进行回滚,同时又要在其他表中记录是哪一笔交易记录失败
    为什么因式分解n=pq分别得到pq是求解密钥中d的关键
    DB2 创建数据库
    socket 收发报文小程序
    Zbrush Topogun 备忘
    过度科目理解
    借贷记账思考2015.12.28
  • 原文地址:https://www.cnblogs.com/ccaa/p/12184749.html
Copyright © 2020-2023  润新知