c# 并行运算
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# 并行运算的更多相关文章
- 多线程之任务: Task 基础, 多任务并行执行, 并行运算(Parallel)
Task - 基于线程池的任务(在 System.Threading.Tasks 命名空间下) 多 Task 的并行执行 Parallel - 并行计算(在 System.Threading.Task ...
- Scalaz(59)- scalaz-stream: fs2-程序并行运算,fs2 running effects in parallel
scalaz-stream-fs2是一种函数式的数据流编程工具.fs2的类型款式是:Stream[F[_],O],F[_]代表一种运算模式,O代表Stream数据元素的类型.实际上F就是一种延迟运算机 ...
- Scalaz(52)- scalaz-stream: 并行运算-parallel processing concurrently by merging
如果scalaz-stream真的是一个实用的数据流编程工具库的话,那它应该能处理同时从多个数据源获取数据以及把数据同时送到多个终点(Sink),最重要的是它应该可以实现高度灵活的多线程运算.但是:我 ...
- SQL Server调优系列基础篇(并行运算总结)
前言 上三篇文章我们介绍了查看查询计划的方式,以及一些常用的连接运算符.联合运算符的优化技巧. 本篇我们分析SQL Server的并行运算,作为多核计算机盛行的今天,SQL Server也会适时调整自 ...
- SQL Server调优系列基础篇(并行运算总结篇二)
前言 上一篇文章我们介绍了查看查询计划的并行运行方式. 本篇我们接着分析SQL Server的并行运算. 闲言少叙,直接进入本篇的正题. 技术准备 同前几篇一样,基于SQL Server2008R2版 ...
- 重新想象 Windows 8 Store Apps (43) - 多线程之任务: Task 基础, 多任务并行执行, 并行运算(Parallel)
[源码下载] 重新想象 Windows 8 Store Apps (43) - 多线程之任务: Task 基础, 多任务并行执行, 并行运算(Parallel) 作者:webabcd 介绍重新想象 W ...
- ahjesus C# 4.0 Parallel 并行运算
Parallel.For - for 循环的并行运算 Parallel.ForEach - foreach 循环的并行运算 Parallel.Invoke - 并行调用多个任务 Task - 任务,基 ...
- Parallel并行运算实例
并行运算Parallel,是.net 4.0版本里添加的新处理方式,主要充分利用CPU.任务并发的模式来达到提高运算能力.简单理解为每个CPU都在处理任务,而不会让它们空闲下来. 直接看实例: nam ...
- Python串行运算、并行运算、多线程、多进程对比实验
转自:http://www.redicecn.com/html/Python/20111223/355.html Python发挥不了多核处理器的性能(据说是受限于GIL,被锁住只能用一个CPU核心, ...
随机推荐
- edtftpj让Java上传FTP文件支持断点续传
在用Java实现FTP上传文件功能时,特别是上传大文件的时候,可以需要这样的功能:程序在上传的过程中意外终止了,文件传了一大半,想从断掉了地方继续传:或者想做类似迅雷下载类似的功能,文件太大,今天传一 ...
- filter:alpha(opacity=100,style=1)
filter:alpha(opacity=100,style=1) 1.opacity属性:设置透明度,取值0至100之间的任意数值,100表示完全不透明: 2.style属性:设置渐变风格: 0表示 ...
- 星外虚拟主机跨web目录文件读取漏洞
星外虚拟主机跨目录读取文件漏洞,需要一定条件. 问题发生在以下文件,这些文件都没有严格的设置执行权限,当前的IIS用户能够顺利的利用它们执行命令: c:\windows\7i24IISLOG.exe ...
- 【液晶模块系列基础视频】3.1.fatfs文件系统的移植及接口函数的使用
============================== 技术论坛:http://www.eeschool.org 博客地址:http://xiaomagee.cnblogs.com 官方网店:h ...
- JavaScript的My97Date日期工具类的使用
开发人员最喜欢的事情就是有工具然后拿来直接使用(. ~ .) 使用截图: 1.设置input标签 2.根据其DEMO文件,引入,进行事件处理 3.效果如图 4.效果如图 代码: <!DOCTYP ...
- 手动编译安装lanmp centos6.5 64位
对于新手来说一个很大的问题就是连源码包都在到在哪下载,还有就是软件的依赖关系 如果网卡也不会配置,请翻看我的其他文章 这就是基本所需的源码包了 http://pan.baidu.com/s/1kTxb ...
- 《编写可维护的 Javascript》读书笔记(附录 A 部分):Javascript 编码风格指南(1)原始值
记录一下比较有用的编码规范(该指南是基于 Java 语言编码规范和 Javascript 编程规范,同时结合作者 Nicholos Zakas 的个人经验和喜好). 一些关于格式(包括缩进.行的长度. ...
- 利用反射得到android存储路径
获得android手机的存储路径: public String getPrimaryStoragePath(){ try{ StorageManager sm = (StorageManager) c ...
- oracle 多表查询
1.注意点 在查询过程中,不确定数据库表中的数据量,先查询数据量,数据量较大,则不能直接查询(select * from emp),如果数据量较大,直接查询容易造成死机或者数据读取较慢,如果较小可以查 ...
- Python - KMP算法
def kmp_match(tex, pat): n = len(tex) m = len(pat) tex = '0' + tex pat = '0' + pat pi = [] pi.append ...