NET中并行开发优化

让我们考虑一个简单的编程挑战:对大数组中的所有元素求和。现在可以通过使用并行性来轻松优化这一点,特别是对于具有数千或数百万个元素的巨大阵列,还有理由认为,并行处理时间应该与常规时间除以CPU核心数一样多。事实证明,这一壮举并不容易实现。我将向您展示几种并行执行此操作的方法,它们如何改善或降低性能以及以某种方式影响性能的所有细节。

简单的循环方法

private const int ITEMS = 500000;
private int[] arr = null; public ArrayC()
{
arr = new int[ITEMS];
var rnd = new Random();
for (int i = 0; i < ITEMS; i++)
{
arr[i] = rnd.Next(1000);
}
} public long ForLocalArr()
{
long total = 0;
for (int i = 0; i < ITEMS; i++)
{
total += int.Parse(arr[i].ToString());
} return total;
} public long ForeachLocalArr()
{
long total = 0;
foreach (var item in arr)
{
total += int.Parse(item.ToString());
} return total;
}

只需要迭代循环就可以计算出结果,超级简单,这里没有用直接相加求出结果,原因是直接求出结果,发现每次基本的运行都比并行快,但是实际上,并行处理没有那么简单,所以这里的加法就简单的处理下total += int.Parse(arr[i].ToString())。现在,让我们尝试用并行性来打败数组迭代吧。

首次尝试

private object _lock = new object();

public long ThreadPoolWithLock()
{
long total = 0;
int threads = 8;
var partSize = ITEMS / threads;
Task[] tasks = new Task[threads];
for (int iThread = 0; iThread < threads; iThread++)
{
var localThread = iThread;
tasks[localThread] = Task.Run(() =>
{
for (int j = localThread * partSize; j < (localThread + 1) * partSize; j++)
{
lock (_lock)
{
total += arr[j];
}
}
});
} Task.WaitAll(tasks);
return total;
}

请注意,您必须使用localThread变量来“保存”该iThread时间点的值。否则,它将是一个随着for循环前进而变化的捕获变量。当数据最后打的时候并行已经比普通的快了,但是发现快的不多,说明还可以优化

再次优化

public long ThreadPoolWithLock2()
{
long total = 0;
int threads = 8;
var partSize = ITEMS / threads;
Task[] tasks = new Task[threads];
for (int iThread = 0; iThread < threads; iThread++)
{
var localThread = iThread;
tasks[localThread] = Task.Run(() =>
{
long temp = 0;
for (int j = localThread * partSize; j < (localThread + 1) * partSize; j++)
{
temp += int.Parse(arr[j].ToString());
} lock (_lock)
{
total += temp;
}
});
} Task.WaitAll(tasks);
return total;
}

增加设置临时变量,减少lock次数,发现运行效果已经有质的提高,提高了几倍。忽然想起,有个Parallel.For的方法,研究性能是否可以更快。

Parallel.For优化

public long ParallelForWithLock()
{
long total = 0;
int parts = 8;
int partSize = ITEMS / parts;
var parallel = Parallel.For(0, parts, new ParallelOptions(), (iter) =>
{
long temp = 0;
for (int j = iter * partSize; j < (iter + 1) * partSize; j++)
{
temp += int.Parse(arr[j].ToString());
} lock (_lock)
{
total += temp;
}
});
return total;
}

运行结果比普通迭代快,但是没有ThreadPool快,但是觉得Parallel.For还可以继续优化,也许可以更快

Parallel.For继续优化

public long ParallelForWithLock2()
{
long total = 0;
int parts = 8;
int partSize = ITEMS / parts;
var parallel = Parallel.For(0, parts,
localInit: () => 0L, // Initializes the "localTotal"
body: (iter, state, localTotal) =>
{
for (int j = iter * partSize; j < (iter + 1) * partSize; j++)
{
localTotal += int.Parse(arr[j].ToString());
} return localTotal;
},
localFinally: (localTotal) => { total += localTotal; });
return total;
}

运行效果已经很快,和ThreadPool优化过的差不多,有些时候更快

结论和总结

并行化优化肯定可以提高性能,但是这取决于很多因素,每个案例都应该进行测量和检查。
当各种线程需要通过某种锁定机制相互依赖时,性能会显着降低。

50万数据运行结果

NET中并行开发优化的更多相关文章

  1. 使用ThinkPHP开发中MySQL性能优化的最佳21条经验

    使用ThinkPHP开发中MySQL性能优化的最佳21条经验讲解,目前,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才需要担心的事,而这更 ...

  2. 在 Android开发中,性能优化策略十分重要

    在 Android开发中,性能优化策略十分重要本文主要讲解性能优化中的布局优化,希望你们会喜欢.目录 示意图 1. 影响的性能 布局性能的好坏 主要影响 :Android应用中的页面显示速度 2. 如 ...

  3. .NET下的并行开发

    并行开发一直是程序员在开发项目中遇到的一道坎,但为了迎合硬件的升级,面对高端多核的处理器,并行编程势在必行.在.NET平台下的开发支持并行模式,下面用一个实际项目说明并行的高效率和神奇之处. 在优化中 ...

  4. 8天玩转并行开发——第八天 用VS性能向导解剖你的程序

    原文 8天玩转并行开发——第八天 用VS性能向导解剖你的程序 最后一篇,我们来说说vs的“性能向导",通常我们调试程序的性能一般会使用Stopwatch,如果希望更加系统的了解程序,我们就需 ...

  5. 【SQL系列】深入浅出数据仓库中SQL性能优化之Hive篇

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[SQL系列]深入浅出数据仓库中SQL性能优化之 ...

  6. 并行开发 8.用VS性能向导解剖你的程序

    原文:8天玩转并行开发——第八天 用VS性能向导解剖你的程序 最后一篇,我们来说说vs的“性能向导",通常我们调试程序的性能一般会使用Stopwatch,如果希望更加系统的了解程序,我们就需 ...

  7. [.net 面向对象程序设计进阶] (24) 团队开发利器(三)使用SVN多分支并行开发(下)

    [.net 面向对象程序设计进阶] (24) 团队开发利器(三)使用SVN多分支并行开发(下) 本篇导读: 接上篇继续介绍SVN的高级功能,即使用分支并行开发.随着需求的不断变更,新功能的增加.特别是 ...

  8. .NET下的并行开发(案例代码)

    以下主要是通过一个报表处理程序来说明并行开发的方式.对于数据冲突和共享,可以通过对象数组解决.设计到并行的核心代码已用红色标出.在并行程序的处理上,需要把原来串行的子公司变成一个一个类的对象,让所有的 ...

  9. 【翻译】CEDEC2014跨世代多平台并行开发PS4版如龙维新开发的一年

    本篇PPT讲述的是如龙4的开发过程中,集中在PS3和PS4并行开发中所遇到和解决的一些问题.如64位指针,DX9向DX11移植API的问题,以及在PS4上使用并行渲染在1080P下让FPS达到60等. ...

随机推荐

  1. 发现eclipse红叉,查看markers发现Target runtime Apache Tomcat v8.0 is not defined

    导入以前的项目(Markers中注意查看,就在console选项卡旁边),报以下错误,但不影响操作: Faceted Project Problem        Target runtime Apa ...

  2. leetcode 130 Surrounded Regions(BFS)

    Given a 2D board containing 'X' and 'O', capture all regions surrounded by 'X'. A region is captured ...

  3. ACM学习历程—HDU5410 CRB and His Birthday(动态规划)

    Problem Description Today is CRB's birthday. His mom decided to buy many presents for her lovely son ...

  4. Jenkins持续集成环境搭建

    1部署Jenkins Jenkins部署很简单,只需建立一个新应用,将Jenkins的war包部署进去,再分配好权限就可以了. 1.1创建应用 建立一个新Nginx应用:jenkins.com 1.2 ...

  5. 解决CentOS 7安装zabbix 3.0 无法启动zabbix-server的问题[segfault at 18 ip 00007f78842b4bd0 sp 00007fff1995a818 error 4 in libpthread-2.17.so[7f78842ab000+16000]]

    解决CentOS 7安装zabbix 3.0 无法启动zabbix-server的问题 [root@localhost sbin]# service zabbix-server start Redir ...

  6. AI-Info-Micron-Insight:将您的游戏技能变成一份工作

    ylbtech-AI-Info-Micron-Insight:将您的游戏技能变成一份工作 1.返回顶部 1. 将您的游戏技能变成一份工作 听起来不现实? 一位来自著名商学院的教授不这么认为.他认为,金 ...

  7. MODBUS ASCII和RTU两种模式的区别、优缺点

    转自:http://blog.sina.com.cn/s/blog_89f286ad0102uzju.html 下表是MODBUS ASCII协议和RTU协议的比较: 协议 开始标记 结束标记 校验 ...

  8. winform 控件合集2

    http://www.cnblogs.com/peterzb/archive/2009/06/18/1505424.html 包含自定义绘制的ListBox, 带拖动,图片显示, 内嵌其它控件, 打印 ...

  9. linux下使用c判断文件夹是否为空的小程序

    自己写了一个 判断文件夹是否为空的小代码 //文件夹操作相关的函数的帮助$: man 3 readdir #include <stdio.h> #include <sys/types ...

  10. Ajax的调试错误信息的输出

    error: function(xhr, status, error) { console.log(xhr); console.log(status); console.log(error); }