.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();
        }
    }
}

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

图1、性能比较

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

 

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

 

时间: 2024-10-30 13:08:34

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

MySQL 怎么把一个数组插入数据库?

问题描述 MySQL 怎么把一个数组插入数据库? array(22) { ["user_name"]=> array(4) { [0]=> string(3) "name1" [1]=> string(3) "name2" [2]=> string(3) "name3" [3]=> string(3) "name4" } ["sex"]=> array

PHP中使用array函数新建一个数组_php实例

PHP 中的数组实际上是一个有序映射.映射是一种把 values 关联到 keys 的类型.此类型在很多方面做了优化,因此可以把它当成真正的数组,或列表(向量),散列表(是映射的一种实现),字典,集合,栈,队列以及更多可能性.由于数组元素的值也可以是另一个数组,树形结构和多维数组也是允许的. array (PHP 4, PHP 5) array - 新建一个数组 说明 复制代码 代码如下: array array ([ mixed $... ] ) 返回根据参数建立的数组.参数可以用 => 运算

Photoshop可否在同一图层选取其中一个文字填充渐变色

  Photoshop可以在同一图层选取其中一个文字填充渐变色.把文字层转换成图层,然后在层面版上按住CTRL,用鼠标点击转换成图层的文字层就能选中全部文字,然后按住ALT键,就会出现+_的符号,然后选中不需要的文字,那么留下的就是需要的文字,在用渐变色填充就可以了. 分类: PS入门教程

[经典面试题][谷歌]一个大小为n的数组,里面的数都属于范围[0, n-1],有不确定的重复元素,找到至少一个重复元素

题目 一个大小为n的数组,里面的数都属于范围[0, n-1],有不确定的重复元素,找到至少一个重复元素,要求O(1)空间和O(n)时间. 思路一 寻找重复元素,很容易想到建立哈希表来完成,遍历一遍数组就可以将每个元素映射到哈希表中.如果哈希表中已经存在这个元素则说明这就是个重复元素.这种方法可以很方便的在O(n)时间内完成对重复元素的查找.可是题目要求在O(1)的空间.因此采用哈希表这种解法肯定在空间复杂度上是不符合要求的.题目中数组中所以数字都在[0, n-1]区间范围内,因此哈希表的大小为n

用c++写了一个函数判断一个数组是否包含另一个数组 但是总是返回-1 请大神们帮忙看看错在哪里

问题描述 用c++写了一个函数判断一个数组是否包含另一个数组 但是总是返回-1 请大神们帮忙看看错在哪里 int substr_index( const char substr[], const char str[]) { int flag = -1; int sizeOfSubstr = sizeof(substr)/sizeof(char); int sizeOfStr = sizeof(str)/sizeof(char); for (int i = 0; i < sizeOfStr; i+

变量名-PHP文件为什么会直接返回一个数组?

问题描述 PHP文件为什么会直接返回一个数组? <?phpreturn array( 'app' => __DIR__.'/../app' 'public' => __DIR__.'/../public' 'base' => __DIR__.'/..'); 数组无变量名, require这个文件时怎么使用数组里的数据? 解决方案 $a = require 'config.php';print_r($a); 解决方案二: 换成 $a = include 'a.php' 解决方案三:

有一个数组 3 7 5 0 2 9 8,用冒泡法对它排序,要求写出每一趟排序的结果。

问题描述 有一个数组 3 7 5 0 2 9 8,用冒泡法对它排序,要求写出每一趟排序的结果. 有一个数组 3 7 5 0 2 9 8,用冒泡法对它排序,要求写出每一趟排序的结果. 解决方案 3 7 5 0 2 9 83 5 0 2 7 8 93 0 2 5 7 8 90 2 3 5 7 8 9 解决方案二: 你没有说是按照从大到小还是从小到大顺序 解决方案三: 冒泡网上一搜就出来了啊 # include <stdio.h># define N 7void bubble_sort(int a[

php使用数组填充下拉列表框的方法

 本文实例讲述了php使用数组填充下拉列表框的方法.分享给大家供大家参考.具体实现方法如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 <?php $data = array( (object)array("titulo"=>"Ford", "valor"=>"opcion1&quo

php中如何初始化一个数组

数组 初始化一个数组一般有2种方法:一个是单独给数组中的元素赋值:还有一种是把所有的元素一起初始化.下面简要介绍初始化数组的2种方法:第一种方法:$a["color"]="red";$a["taste"]="sweet";$a["shape"]="round";$a["name"]="apple";$a[3]=4;第二种方法:$a=array(&q