使用多线程的利弊

转载自Intel:http://software.intel.com/zh-cn/blogs/2013/04/09/?utm_campaign=CSDN&utm_source=intel.csdn.net&utm_medium=Link&utm_content=%20Multicore%20-duoxiancheng数据库

 

1. Amdahl定律编程

     一个很简单的量化公式,用来计算一个程序中串行部分所占多少对程序加速比的影响或者用来计算计算机硬件配置中某个设备的速度提升可以将整个系统的速度提升多少。多线程

     假设一个串行程序执行的总时间为1,不能被并行化的部分占的时间比例为p,即串行化的部分为p,可并行化的时间为:1-p。若是用n个核用来加速的话,加速比为:架构

 

李超

    若是一个程序中只有50%部分可以被并行化,那么即便使用100个核,能达到的最好的加速比为1.98,即不会达到2.除非n无穷大。并发

     Amdahl就像克莱姆准则同样不能用于实际中,由于很难精确的使用这个公式。咱们须要找到程序中全部的串行部分和并行部分。串行部分不单单存在于代码中必需的依赖关系,可能还有底层库函数中的串行,还有操做系统的串行部分,甚至还有硬件自己的串行部分。异步

 

2. 异步应用程序的实现方法函数

     常见的实现方式有:多线程+同步,异步I/O,非阻塞I/O,信号,事件。异步I/O和非阻塞I/O并非一回事,固然在有些场合下也会混淆使用。通常来讲,异步侧重于表达并行,两个执行流能够同时进行。非阻塞通常还包含一个查询的过程,由于要查询所要进行的操做是否完成。优化

     异步I/O使用起来难度比多线程大,理解和维护起来的难度通常也比多线程麻烦。一样使用信号也是这个缺点,由于单个线程可使用同步的方式,线程之间可使用信号来通讯。这样就好像一我的同时作不少件事情和一个团队来协做来完成这些事情的区别同样。后者的执行逻辑会更加清晰,并且多线程+同步的方式可以实现全部异步I/O带来的优点。操作系统

     使用UNIX信号的方式有严重的局限性,由于收到信号后全部的逻辑放在一个信号处理函数中执行,这并非信号处理函数设计的初衷。并且,使用信号会显得程序的组织结构比较混乱,维护起来比较麻烦。.net

     事件流也是实现异步应用程序的一种方式。通常系统底层会将应用程序收到的各类事件缓冲到一个队列中,而后又底层负责将各类事件对应到一个回调函数上,串行的处理各个事件,即调用各个回调函数。这种方式的最大缺点就是有些事件的回调函数的执行事件比较长,会致使其余事件不能获得很好地相应。在Windows系统的.NET架构上,事件+回调函数是使用的比较多的一种方式。事件流的缺点在于其处理的顺序性。固然事件流+回调函数+多线程是一种不错的选择。

 

3. 编程模型

     各个编程模型的计算能力是等价的,可是对问题抽象层次是不一样的。汇编语言在表示程序的结构方面显得比较笨拙,可是使用C语言就将程序的设计结构显式的表现出来了。使用C语言进行数据封装和多态处理显得很笨拙,使用C++就能很好地处理这个问题。使用关系数据库在解决大规模数据问题上显得很笨拙,使用Map-Reduce就能很好的处理某些问题。非线程代码不能显式的表达操做的同步性,使用线程代码就能很好的表达出这些同步性。线程源代码让独立的模块或者松耦合的模块更加清楚的表现出来。

     不一样的编程模型对应着不一样的抽象层次,对于问题域的抽象恰到好处的抽象模型有助于咱们解决更复杂的问题。

 

4. 什么状况下使用线程

     使用线程是有代价的,若是程序是计算密集型且每一步都有依赖,那么使用线程反而会致使效率降低,由于多个线程之间须要切换,还要负责维护锁,信号量等设施。对于可并行的计算密集型问题和I/O与计算可重叠的问题使用多线程通常会达到显著的效果。程序中有多个可并发的模块的时候,使用线程也能提升程序的响应速度。

 

如需更全面地了解编译器优化,请参阅优化注意事项:http://software.intel.com/zh-cn/articles/optimization-notice#opt-cn

相关文章
相关标签/搜索