Processing math: 100%

.NET(C#) Internals: 以一个数组填充的例子初步了解.NET 4.0中的并行(一)

简介:

引言

随着CPU多核的普及,编程时充分利用这个特性越显重要。本文首先用传统的嵌套循环进行数组填充,然后用.NET 4.0中的System.Threading.Tasks提供的Parallel Class来并行地进行填充(当然这里也用到嵌套循环),通过对比发现其中差异。主要内容如下:

  • 通常的数组填充
  • 并行的组数填充
  • 性能比较
  • System.Threading.Tasks分析,这个将在续篇.NET(C#) Internals: 以一个数组填充的例子初步了解.NET 4.0中的并行(二)中介绍

1、通常的数组填充

首先看如下代码:

using System;

namespace ParallelForSample
{
  public class SingleCore
  {
    public static void Calculate(int calcVal)
    {
      Utility util = new Utility();
      util.Start();

      int[,] G = new int[calcVal, calcVal];
      for (int k = 0; k < calcVal; k++)
        for (int i = 0; i < calcVal; i++)
          for (int j = 0; j < calcVal; j++)
            G[i, j] = Math.Min(G[i, j], G[i, k] + G[k, j]);
      util.Stop();

    }
  }
}
上面的粗体红色显示的几行代码就是实现数组填充,这个很好理解不用多费口舌。补充说明的是:上面的Utility是为了统计性能而编写的一个类,它主要就是用到了 Stopwatch对象——它提供一组方法和属性,可用于准确地测量运行时间。Utility的代码如下:
  public class Utility
    {
        private Stopwatch _stopwatch;
        public void Start()
        {
            _stopwatch = new Stopwatch();
            _stopwatch.Start();
        }

        public void Stop()
        {
            _stopwatch.Stop();
            TimeSpan ts = _stopwatch.Elapsed;
            string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
                ts.Hours, ts.Minutes, ts.Seconds,
                ts.Milliseconds / 10);
            Console.WriteLine("Time taken : {0}", elapsedTime);
        }
    }
利用它我们就可以对数组填充所耗费的时间进行计算了。

2、并行的组数填充

为了充分利用CPU的多核,我们编写如下代码:

using System;
using System.Threading.Tasks;

namespace ParallelForSample
{
  public class MultiCore
  {
    public static void Calculate(int calcVal)
    {
      Utility util = new Utility();
      util.Start();

      int[,] G = new int[calcVal, calcVal];

      Parallel.For(0, calcVal,
        delegate(int k)
        {
          Parallel.For(0, calcVal, delegate(int i)
          {
            for (int j = 0; j < calcVal; j++)
              G[i, j] = Math.Min(G[i, j], G[i, k] + G[k, j]);
          });
        }
      );

      util.Stop();
    }
  }
}

留意上面的红色粗体显示的几行代码,它利用了Parallel.For Method (Int32, Int32, Action<Int32>)方法,Parallel类位于命名空间System.Threading.Tasks中,它支持并行循环。此Parallel.For方法使得它里面的迭代可能并行地运行,注意到上述代码中它的第三个参数是一个委托。在(0,calcVal)之间,这个委托将被调用。

3、性能比较

现在我们来测试一下,上面两种方法的执行性能差异如何,下载源码。其实,核心代码已经在上面贴出来了,现在注意是编写实例来测试,代码主要如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ParallelForSample
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Single core");
            SingleCore.Calculate(1000);
            Console.WriteLine("Multi core");
            MultiCore.Calculate(1000);
            Console.WriteLine("Finished");
            Console.ReadKey();
        }
    }
}

运行之后得到如下结果:(不同电脑配置不同,得出结果不同)

image图1、性能比较

从结果可以看出,并行的数组填充比通常的数组填充性能更高。

 

  • System.Threading.Tasks分析,这个将在续篇.NET(C#) Internals: 以一个数组填充的例子初步了解.NET 4.0中的并行(二)中介绍……


 


相关文章
|
5月前
|
测试技术 C#
.NET单元测试使用Bogus或AutoFixture按需填充的几种方式和最佳实践
【7月更文挑战第13天】AutoFixture 和 Bogus 都是流行的 C#库,用于在单元测试中按需填充测试数据。以下是它们的几种使用方式和最佳实践:一、AutoFixture:1.直接定制 2.使用匿名函数 3.实现ICustomization接口 4.使用Build方法。 二、最佳实践Bogus:1.安装2.使用。
艾伟_转载:.NET 4.0中数组的新增功能
  1、两数组是否“相等”?   在实际开发中,有时我们需要比对两个数组是否拥有一致的元素,例如,以下两个数组由于拥有相同的元素,因此被认为是相等的: int[] arr1 = new int[]{1,2,3,4};int[] arr2 = new int[]{1,2,3,4};   在.NET早期版本中,要实现上述数组比对功能,必须自己动手编写一个函数,在其内部使用循环语句逐个比较两个数组的对应元素,才知道这两个数组是否相等。
817 0
.NET webbrowser自动填充登录
HtmlElement name = webBrowser1.Document.GetElementById("ctl00contentloginname"); if (name != null) name.
857 0
|
.NET 开发框架 数据库
asp.net:AJAX+LINQ+TreeView 动态填充多级节点
演示示例为一个学生信息查看菜单:先选择部门,再选择班级,最后选择学生姓名,查看学生信息; 效果图:      采用TreeView的SelectedNodeChanged事件作为一个包含用来显示学生信息的Lable的UpdatePanel的触发器,如下: [xhtml] view plai.
1197 0
|
XML C# 数据格式
.NET(C#):在数组成员上加入XmlElement特性
原文 www.cnblogs.com/mgen/archive/2011/12/04/2276131.html 当对如下类进行XML序列化时: publicclassa {     publicint[] arr =newint[] { 1, 2, 3 }; }   结果会是:             1         2         3       数组字段会成为单独的XML元素。
1022 0