c# 并行运算

1. Parallel.INVOKE() 看实例:

    private static Stopwatch watch = new Stopwatch();

        private static void Run1()
{
Thread.Sleep();
Console.WriteLine("Task 1 takes 2 sec");
}
private static void Run2()
{
Thread.Sleep();
Console.WriteLine("Task 2 takes 3 sec");
} static void Main(string[] args)
{
watch.Start();
Parallel.Invoke(Run1,Run2);
watch.Stop();
Console.WriteLine("Parallel run "+watch.ElapsedMilliseconds +" ms"); watch.Restart();
Run1();
Run2();
watch.Stop();
Console.WriteLine("Normal run "+watch.ElapsedMilliseconds+" ms"); Console.ReadLine();

看结果:

 2.Parallel.For

 看实例:

  watch.Start();
for (int i = ; i < ; i++)
{
for (int j = ; j < ; j++)
{
int sum = ;
sum++;
}
}
watch.Stop();
Console.WriteLine("Normal run " + watch.ElapsedMilliseconds + "ms"); watch.Restart();
watch.Start();
Parallel.For(, , item =>
{
for (int j = ; j < ; j++)
{
int sum = ;
sum += item;
} }); watch.Stop();
Console.WriteLine("ParalleFor run " + watch.ElapsedMilliseconds + "ms"); Console.ReadLine();

看结果:

 

是不是Parallel.For在任何时候都比for要快呢?答案当然是“不是”,要不然微软还留着for干嘛?

看实例:

   var obj = new object();
long num = ;
ConcurrentBag<long> bag = new ConcurrentBag<long>();
watch.Start();
for (int i = ; i < ; i++)
{
for (int j = ; j < ; j++)
{
// int sum = 0;
// sum++;
num++;
}
} watch.Stop();
Console.WriteLine("Normal run "+watch.ElapsedMilliseconds+ "Ms"); watch.Restart(); Parallel.For(, , item =>
{
for (int j = ; j < ; j++)
{
//int sum = 0;
//sum += item;
lock (obj)
{
num++; //全局变量,就要考虑到线程安全了
//这主要是由于并行同时访问全局变量,会出现资源争夺,大多数时间消耗在了资源等待上面。
}
} }); watch.Stop();
Console.WriteLine("ParalleFor run " + watch.ElapsedMilliseconds + "ms"); Console.ReadLine();

结果:(结果不是稳定的,你懂得~)

再看代码:

  Parallel.For(, , i =>
{
Console.Write( i +"\t");
}); Console.ReadLine();

再看结果:

傻孩子,这样你懂了吧~

 3.Parallel.Foreach

//Environment.ProcessorCount能够获取到当前的硬件线程数,所以这里也就开了2个区。
Console.WriteLine(Environment.ProcessorCount);
Console.ReadLine();
//继续我的并发编程; //可以将数据进行分区,每一个小区内实现串行计算;分区采用Create实现; for (int j = ; j < ; j++)
{
Console.WriteLine("\n第{0}次比较", j);
ConcurrentBag<int> bag = new ConcurrentBag<int>();
watch.Start(); for (int i = ; i < ; i++)
{
bag.Add(i);
} Console.WriteLine("串行计算:集合有{0},总共耗时:{1}",bag.Count,watch.ElapsedMilliseconds); GC.Collect();
bag = new ConcurrentBag<int>();
watch.Restart();
Parallel.ForEach(Partitioner.Create(, ), i =>
{
for (int m = i.Item1; m < i.Item2; m++)
{
bag.Add(m);
}
});
Console.WriteLine("并行计算:集合有:{0},总共耗时:{1}", bag.Count, watch.ElapsedMilliseconds); GC.Collect();
watch.Stop();
} Console.ReadLine();

结果:

4.parallel 中途退出循环

Break: 当然这个是通知并行计算尽快的退出循环,比如并行计算正在迭代100,那么break后程序还会迭代所有小于100的。

Stop:这个就不一样了,比如正在迭代100突然遇到stop,那它啥也不管了,直接退出。

 

    ConcurrentBag<long> bag = new ConcurrentBag<long>();
watch.Start(); Parallel.For(,, (i, state) =>
{
if (bag.Count == )
{
state.Break();
//当数量达到300个时,会立刻停止;可以看到结果"Bag count is 300",如果用break,可能结果是300多个或者300个,大家可以测试一下。
return;
}
bag.Add(i); });
watch.Stop();
Console.WriteLine("Bag count is "+bag.Count+" times is "+watch.ElapsedMilliseconds);

 异常处理

由于Task的Start方法是异步启动的,所以我们需要额外的技术来完成异常处理

 try
{
var parallelExceptions = new ConcurrentQueue<Exception>();
Parallel.For(, , (i) =>
{
try
{
throw new InvalidOperationException("并行任务中出现的异常");
}
catch (Exception e)
{
parallelExceptions.Enqueue(e);
}
if (parallelExceptions.Count > )
throw new AggregateException(parallelExceptions);
});
}
catch (AggregateException err)
{
foreach (Exception item in err.InnerExceptions)
{
Console.WriteLine("异常类型:{0}{1}来自:
{}{}异常内容:{}", item.InnerException.GetType(),
Environment.NewLine, item.InnerException.Source,
Environment.NewLine, item.InnerException.Message);
}
}
Console.WriteLine("主线程马上结束");
Console.ReadKey();
static void Main(string[] args)
{
try
{
Parallel.Invoke(Run1, Run2);
//这个捕获
//在不同的模式下,会有不同结果地呀;
//debug 模式下,会停止的
//realse 模式下就可以获取异常;
}
catch (AggregateException ex)
{
foreach (var single in ex.InnerExceptions)
{
Console.WriteLine(single.Message);
}
} Console.Read();
} static void Run1()
{
Thread.Sleep();
throw new Exception("我是任务1抛出的异常");
} static void Run2()
{
Thread.Sleep(); throw new Exception("我是任务2抛出的异常");
}

实例二

 try
{
go1(); //这样的异常只能捕获其中一个地呀; go2();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
watch.Stop();
Console.WriteLine("Normal run :" + watch.ElapsedMilliseconds);
//尼玛的,这样的异常,居然捕获不到的地呀

默认的情况下,底层机制会尽可能多的使用硬件线程,然而我们使用手动指定的好处是我们可以在2,4,8个硬件线程的情况下来进行测量加速比。

class Program
{
static void Main(string[] args)
{
var bag = new ConcurrentBag<int>(); ParallelOptions options = new ParallelOptions(); //指定使用的硬件线程数为1
options.MaxDegreeOfParallelism = ; Parallel.For(, , options, i =>
{
bag.Add(i);
}); Console.WriteLine("并行计算:集合有:{0}", bag.Count); }
}

c# 并行运算的更多相关文章

  1. 多线程之任务: Task 基础, 多任务并行执行, 并行运算(Parallel)

    Task - 基于线程池的任务(在 System.Threading.Tasks 命名空间下) 多 Task 的并行执行 Parallel - 并行计算(在 System.Threading.Task ...

  2. Scalaz(59)- scalaz-stream: fs2-程序并行运算,fs2 running effects in parallel

    scalaz-stream-fs2是一种函数式的数据流编程工具.fs2的类型款式是:Stream[F[_],O],F[_]代表一种运算模式,O代表Stream数据元素的类型.实际上F就是一种延迟运算机 ...

  3. Scalaz(52)- scalaz-stream: 并行运算-parallel processing concurrently by merging

    如果scalaz-stream真的是一个实用的数据流编程工具库的话,那它应该能处理同时从多个数据源获取数据以及把数据同时送到多个终点(Sink),最重要的是它应该可以实现高度灵活的多线程运算.但是:我 ...

  4. SQL Server调优系列基础篇(并行运算总结)

    前言 上三篇文章我们介绍了查看查询计划的方式,以及一些常用的连接运算符.联合运算符的优化技巧. 本篇我们分析SQL Server的并行运算,作为多核计算机盛行的今天,SQL Server也会适时调整自 ...

  5. SQL Server调优系列基础篇(并行运算总结篇二)

    前言 上一篇文章我们介绍了查看查询计划的并行运行方式. 本篇我们接着分析SQL Server的并行运算. 闲言少叙,直接进入本篇的正题. 技术准备 同前几篇一样,基于SQL Server2008R2版 ...

  6. 重新想象 Windows 8 Store Apps (43) - 多线程之任务: Task 基础, 多任务并行执行, 并行运算(Parallel)

    [源码下载] 重新想象 Windows 8 Store Apps (43) - 多线程之任务: Task 基础, 多任务并行执行, 并行运算(Parallel) 作者:webabcd 介绍重新想象 W ...

  7. ahjesus C# 4.0 Parallel 并行运算

    Parallel.For - for 循环的并行运算 Parallel.ForEach - foreach 循环的并行运算 Parallel.Invoke - 并行调用多个任务 Task - 任务,基 ...

  8. Parallel并行运算实例

    并行运算Parallel,是.net 4.0版本里添加的新处理方式,主要充分利用CPU.任务并发的模式来达到提高运算能力.简单理解为每个CPU都在处理任务,而不会让它们空闲下来. 直接看实例: nam ...

  9. Python串行运算、并行运算、多线程、多进程对比实验

    转自:http://www.redicecn.com/html/Python/20111223/355.html Python发挥不了多核处理器的性能(据说是受限于GIL,被锁住只能用一个CPU核心, ...

随机推荐

  1. 【BZOJ】1878: [SDOI2009]HH的项链(树状数组)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1878 我太弱了,看题解才过的. 一开始看到此题,我想了想在线做法,但之后觉得这个想法可能是错的:维护 ...

  2. BZOJ3091: 城市旅行

    Description Input Output Sample Input 4 5 1 3 2 5 1 2 1 3 2 4 4 2 4 1 2 4 2 3 4 3 1 4 1 4 1 4 Sample ...

  3. serv-u and hway3.0

    一个非常好用的su提权脚本,在支持php的环境下,目录可读可写,基本秒杀. <? //HWay && Serv-U by r00t //r00t@007team.net //ww ...

  4. 微博java SDK介绍及使用说明

    转自:作者:新浪微博 开放平台 @MUNTO_AKIRA http://open.weibo.com/blog/%E5%BE%AE%E5%8D%9Ajava-sdk%E4%BB%8B%E7%BB%8D ...

  5. optimize table table_name myisam mysql自动清除删除过留下的空记录

    optimize table table_name 这个可以清除你表里面的空记录,每次清除的时候记得锁表 lock tables table_name  write|read; unlock tabl ...

  6. AsyncTask的基本使用

    // String --> doInBackground(Params... params)的参数 // File --> publishProgress(Progress... valu ...

  7. Mysql 定时备份操作

    1.创建保存备份文件的路径/mysqldata #mkdir /bak/mysqlbak 2.创建/usr/sbin/bakmysql文件 #vi /usr/sbin/bakmysql.sh 3.写入 ...

  8. Pentium II paging mechanism

    COMPUTER ORGANIZATION AND ARCHITECTURE DESIGNING FOR PERFORMANCE NINTH EDITION To understand the str ...

  9. Python For Data Analysis -- IPython

    IPython Basics 首先比一般的python shell更方便一些 比如某些数据结构的pretty-printed,比如字典 更方便的,整段代码的copy,执行 并且可以兼容部分system ...

  10. static的作用,this(),super()用法

    1:static{}表示静态代码块:在java虚拟机(jvm)加载该类时,会执行这个代码块一次,静态代码块在new()对象之前就加载了 2: this()与surper()区别:surper()是从子 ...