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. Memcached、Redis OR Tair

    一.前言 非关系型数据库(NoSQL = Not Only SQL)的产品非常多,常见的有Memcached.Redis.MongoDB等优秀开源项目,相关概念和资料网上也非常丰富,不再重复描述,本文 ...

  2. C#设计模式——抽象工厂模式(原文转自:http://blog.jobbole.com/78059/)

    一.引言 在上一专题中介绍了工厂方法模式,工厂方法模式是为了克服简单工厂模式的缺点而设计出来的,简单工厂模式的工厂类随着产品类的增加需要增加额外的代码),而工厂方法模式每个具体工厂类只完成单个实例的创 ...

  3. 如何用Apache POI操作Excel文件-----如何对一个单元格加注解?

    有的时候,我们需要通过操作Apache POI,在生成Cell数据的同时,能对其生成的Cell,加上注解(comments),类似于下面的. 那么对于这种情况,我们的代码应该如何写呢? 借花献佛,我就 ...

  4. 分布式文件系统FastDFS原理介绍

    在生产中我们一般希望文件系统能帮我们解决以下问题,如:1.超大数据存储:2.数据高可用(冗余备份):3.读/写高性能:4.海量数据计算.最好还得支持多平台多语言,支持高并发. 由于单台服务器无法满足以 ...

  5. Frenetic Python实验(一)

    Follow: Github-Frenetic 准备: 所有的实验,第一步都需要开启控制器,命令: $ frenetic http-controller --verbosity debug 每一个实验 ...

  6. DirectX基础学习系列8 渐进网格以及外接体

    1 IUnknown--> ID3DXBUFFER D3D泛型接口: GetBufferPointer Retrieves a pointer to the data in the buffer ...

  7. markdown 书写表格

    Tables Are Cool col 3 is right-aligned $1600 col 2 is centered $12 zebra stripes are neat $1 Refs ma ...

  8. 看StackOverflow如何用25台服务器撑起5.6亿的月PV

    问答社区网络 StackExchange 由 100 多个网站构成,其中包括了 Alexa 排名第 54 的 StackOverflow.StackExchang 有 400 万用户,每月 5.6 亿 ...

  9. 大话数据结构(八)Java程序——双向链表的实现

    线性链表--双向链表 双向链表定义: 双向链表(double linked list): 是在单表单的每个结点中,再设置一个指向前驱结点的指针域.因此,在双向链表中的结点都有两个指针域,一个指向前驱, ...

  10. <?php set_time_limit(10);

    <?php include('w_fun.php'); set_time_limit(10); Fatal error: Maximum execution time of 10 seconds ...