• 并行编程(一)


       随着多核时代的到来,并行开发越来越展示出它的强大威力。在了解并行开发之前,我们先来了解两个法则“Amdahl”和“Gustafson”

     Amdahl

      amdahl法则,通过以下公式预测多处理器系统的最大理论性能提升(即加速比,speedup).这个公式也可以应用于运行多核微处理器上的并行算法

      最大加速比(倍数)=1/((1-p)+(p/N))

     其中:

      P 表示能够完全并行运行的代码比例

      N  表示可用的计算单元数(处理器或物理内核数)

      如果一个算法中总任务的50%(p=0.5)可以并行执行,那么在具有两个物理内核的微处理器上的最大加速比为1.33,如一个带有1000份任务的算法,其中有500份并行任务,如果串行版本需要消耗1000秒,那么并行的话就是750秒

      Gustafson 法则

      Gustafson 法则是在固定的时间i内可以执行的工作量

      总工作量(单元数)=s+(N*P)

      其中

      S表示一次执行完成的工作单元数

      P表示每一部分能够完全并行执行的工作单元数

      N表示可用的执行单元数(处理数或者物理内核数)

       如有 50个单元的顺序执行和50是个可以并行的工作单元,你的微处理器是8核的

      那么 总工作量(单元数)=50+(8*50)=450 单元的工作量

    通过上面两个法则,我们就知道并行编程的重要性,下面我们用代码测试一下
    

       

    class Program
        {
            static void Main(string[] args)
            {
                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();
                Run1();
                Run2();
                stopwatch.Stop();
                Console.WriteLine("串行执行所需要的时间{0}", stopwatch.ElapsedMilliseconds);
                stopwatch.Restart();
                Parallel.Invoke(Run1,Run2);
                stopwatch.Stop();
                Console.WriteLine("串行执行所需要的时间{0}", stopwatch.ElapsedMilliseconds);
                Console.ReadLine();
            }
    
            static void Run1()
            {
                Thread.Sleep(5000);
                Console.WriteLine("任务一");
            }
            static void Run2()
            {
                Console.WriteLine("任务二");
                Thread.Sleep(5000);
            }
        }

    结果

     

    可想而知我们的时间就减少了一半,是不是很开心,下面我们对C# 提供给我们的类进行来解释一下

    Parallel类

          在这里我要说一下parallel   提供的是任务而不是线程,任务是架构在线程之上的,任务通过底层算法会根据你电脑的现在状况来选择cup核来为你工作

      在Parallel下面有三个常用的方法invoke,for和forEach。

    1. Invoke 是执行并行方法

           可以传递void返回值得函数

      

    Parallel.Invoke(Run1,Run2);

      也可以传递 lambda表达式,通过Parallel.Invoke 编写的并行执行的代码一定不能依赖于特定的执行顺序,如果需要以特定的执行顺序允许并发代码,后面章节中还会使用高级的东西

     Parallel.Invoke(()=>{ Run1(); },Run2);

       2.Parallel.For

     这个函数对一下数据的检索和添加非常好,

    class Program
        {
            static void Main(string[] args)
            {
                List<int> excel1=null;
                List<int> excel2=null;
                //并行读出两个表的而数据
                Parallel.Invoke(() => { excel1 = GetExcel1(); }, () => { excel2 = GetExcel2();});
    
                //通过并行方式快速将excel2中符合添加的数据加载到excel1表中
                Parallel.For(0,excel2.Count,(i)=>{
                    if(excel2[i]%2==0)
                    { 
                        excel1.Add(excel2[i]);
                    }
                });
    
            }
         
            static List<int> GetExcel1()
            {
                Thread.Sleep(5000);
                Console.WriteLine("任务一");
                List<int> listExcel1 = new List<int>();
                for (int i = 0; i < 100; i++)
                {
                    listExcel1.Add(i);
                }
                return listExcel1;
            }
            static List<int> GetExcel2()
            {
                Thread.Sleep(5000);
                Console.WriteLine("任务二");
                List<int> listExcel1 = new List<int>();
                for (int i = 100; i < 1000; i++)
                {
                    listExcel1.Add(i);
                }
                return listExcel1;
            }
        }

    3. Parallel.ForEach

      对应foreach是分片的,他的运用场合也挺多的,自己慢慢去理解吧

    Parallel.ForEach(Partitioner.Create(0, 3000000), i =>
                {
                   
                        Console.WriteLine("开始{0}-------结束{1}",i.Item1,i.Item2);
                   
                });

  • 相关阅读:
    二进制包安装MySQL数据库
    Nginx 访问日志轮询切割
    安装Nginx服务
    生产环境常见的HTTP状态码列表
    SSH批量部署服务
    MYSQL数据库的优化
    inotify+rsync实现实时同步部署
    rsync同步架构
    Linux shell脚本编程(三)
    Linux shell脚本编程(二)
  • 原文地址:https://www.cnblogs.com/xuehaiyiye/p/5610514.html
Copyright © 2020-2023  润新知