1.2 为什么使用 并行

来源:互联网 发布:东华软件股吧 编辑:程序博客网 时间:2024/04/28 00:12

在程序中使用并行有两大原因:功能和性能分离,事实上,它是使用并发的唯一理由,其他的你看上去难的可以归结为一个理由。

1.2.1 为功能分离使用并行

写软件时功能分离是一个好主意,把相关的代码放在一起,把不想管的代码分离,你会让你的程序更容易理解和测试,并且会减少bugs,你可以使用并行分离单独的功能,甚至在这些单独的功能同事发生;如果没有并行,你就不得不写一个任务切换的框架或者在一个操作中调用不相关的代码。

考虑到一个处理密集的用户界面程序,比如DVD播放器,这样有两个基础功能的程序:不仅要从实时的从硬盘读取数据,解码,发送到显卡和声卡,准确的显示出来。还要响应用户的输入,比如点击暂停或者回到菜单、甚至推出。在一个线程中,程序必须定时检测用户输入,DVD播放的代码与用户界面的代码会交织在一起。通过使用多线程去分隔不同的功能,DVD播放的代码与用户界面的代码不必非交织在一起。一个线程处理用户界面,另一个线程处理播放,他们会相互作用,比如当点击暂停时,直接作用到相关的任务上。

这会提高用户体验,因为用洁面线程可以立刻响应用户请求,即使这个响应是简单的显示一个繁忙的鼠标或者发送一个请等待的消息。类似的,分离线程经常被用来运行后台程序,比如在一个桌面搜索程序中监视文件系统的改变。使用这种方法使每个线程的逻辑更简单,因为他们的相互作用可以被清晰的标示出来,不同的任务逻辑被分散。

线程数是独立于可用的CPU核心数的,因为分隔线程是基于提高性能的概念设计的。

1.2.2 为性能使用并行

多进程系统已经存在很多年了,但是现在只能在在超级计算机,主流框架和大型服务系统中看到了,但是芯片制造商已经设计出了2,4,16或者更多进程的芯片以提供更好的性能。因此,多核桌面计算机,甚至多核嵌入式设备,越来越普遍。这些计算机性能的提高不是运行一个任务越来越快,而是运行多任务能力越来越高。过去程序员不用做任何努力就能看到他们的程序在新一代的处理器中运行的更快。但是现在,如果软件要运行更快必须设计并行任务。程序员必须谨慎并且把并行添加到他们的工具箱。

有两个方法使用并行提高性能,第一个,把一个任务分隔成几部分去同时执行,这回减少总的运行时间。听起来很简单,但他有时是一个很复杂的过程,因为这几部分之间可能是相互关联的。这种分离的处理方法,一个线程执行一部分计算当另一个线程执行不同的部分时,或者每个线程执行相同的操作在不同的数据上。这被称作数据平行。

这种并行运行容易出错的算法被称为尴尬的并行。尽管这意味着你很难使你的代码并行化,这是一个好事情:其他的我遇到的算法都是自然并行或者方便并行的,尴尬并行算法有很多可扩展性-随着可利用硬件线程的增加,算法的并行性可以 被提高,应了那句话:众人拾柴火焰高,对于这些非尴尬并行,你能把它分隔成固定数量的并行任务。

第二个使用并行的方法使使用可利用的并行去解决大问题;同时处理一个文件,2或者10 或者20个线程,尽管这都是是一个数据处理程序。通过对多个数据执行相同的操作,这是一个不同点。它仍然花费相同的时间处理一块数据,但是现在更多的数据可以在相同的时间被处理。显然,也有一些限制,并且这总不会是有益的,但是性能的提高可以让我们做一些新的事情-解决高分辨率的视频处理,不同的图片区域被并行处理。

1.2.3 什么时候不适用并行

知道什么时候不使用并行和知道怎么使用它一样重要。基本上,不适用并行的唯一的原因是成本大于收益。使用并行编程比较难理解,所以需要有一定的知识才能去写或者维护一个多线程程序,增加复杂性会导致更多的bugs。除非性能增加很大或者任务分隔足够清晰有足够的开发时间时间,增加的性能成本大于开发和维护成本,否则不要使用并行。

另外,性能的提升并没有想象的高;运行一个线程有一个与生俱来的开销,因为操作系统必须分配内存资源和栈空间然后增加线程调度。所有的这些都要花费时间。如果任务被运行在这个线程上完成特别快,这真实事件花费小于运行线程的花费,反而会降低程序性能。

线程是有限资源,如果太多的线程同时运行,操作系统可能会变慢。不仅如此,太多的线程会耗尽进程的内存和地址空间,因为每个线程都需要独立的栈空间。一个32为的进程只有4GB的地址空间,如果每个线程有1M栈空间,4096个线程会耗尽所有的地址空间,虽然64位的系统没有直接额的限制,他们仍然是有限的资源,如果你运行太多的线程将会引起问题。虽然线程池可以被用来限制线程的数量,但没有解决他们自己的问题。

如果一个C/S架构的服务端程序为每个连接建立一个线程,这种工作方式在少量连接中会运行的很好,但是同样的技术运行在高连接需求的服务器程序时会耗尽系统资源。

这种场景下使用线程池会取得理想的性能。

最后,越多的线程,操作系统就得做更多的上下文切换。每个上下文切换的时间可以做有用的工作,所以有时增加一个额外的线程可能降低整体性能。基于这个原因,如果你正在尝试最佳的系统性能,你必须要根据硬件并行的熟练决定线程的数量。

对性能的并行使用就像其他的优化策略:它有可能提高程序的性能,但它也使代码复杂,理解困难更多的bugs.所以只有当性能提升时他才是值得的。当然,如果潜在的性能提示仅仅是第二位对于清晰的设计和功能分离,它仍然肯呢过是值得使用。

假如你已经决定要在你的程序中使用并行的话,不论是因为性能,功能分离,或者因为多线程流行,它对于C++程序员意味着什么呢?



0 0