从软件方面讲,这一现象称为“免费的午餐”—只需升级运行应用程序的硬件就能改进其性能。(有关这方面的详细信息,请参阅“面向软件并发的基本转变”,网址为 。)
但如今的模式正在发生改变,处理器的增加使性能得到了改进。多核系统现在已是无处不在了。当然,只有软件能同时执行多个任务,多核方式才能提高性能。如果想让多处理器实现多处理器计算机所承诺的性能提高,必须编写可以使用顺序技术出色完成任务的函数。
分类: C/C++
2010-06-17 13:55:14
本文将介绍以下内容:
|
本文使用了以下技术: 多线程 |
目录
从软件方面讲,这一现象称为“免费的午餐”—只需升级运行应用程序的硬件就能改进其性能。(有关这方面的详细信息,请参阅“面向软件并发的基本转变”,网址为 。)
但如今的模式正在发生改变,处理器的增加使性能得到了改进。多核系统现在已是无处不在了。当然,只有软件能同时执行多个任务,多核方式才能提高性能。如果想让多处理器实现多处理器计算机所承诺的性能提高,必须编写可以使用顺序技术出色完成任务的函数。
并发和并行
现在,程序员有时必须要考虑并行给编程所带来的难题—并发。为了保证响应,需要有某种方式能从输入事件的处理线程卸载响应时间过长的活动。过去这类活动大部分涉及文件 I/O,但现在更多的是涉及与 Web 服务的会话。
Microsoft .NET Framework 提供了异步编程模型和后台工作程序理念,以适应这一常用编程需要。虽然在并行编程中平行编程的复杂性大部分相雷同,但基本模式和目标却各异。多核处理器不会减少并发编程需求,这种技术是用于优化后台活动和系统中的其它计算,目的是提高性能。
去年,Microsoft 发起了“平行计算管理计划”(),该活动不但是要探讨如何构建并有效执行并行程序,而且旨在鼓励创建新一代应用程序,能够将“摩尔红利”转化为客户价值。我将很快研讨一些并行性的思路。Stephen Toub 和 Hazim Shafi 在本期的文章“”介绍了一些我们用于支持这些方法的库和工具。Joe Duffy 在本期的文章“”中讨论了改进并发应用程序安全的技术和方法。
以前,我使用“并发执行机会”一词进一步区分并行与并发编程。如开发人员使用异步编程模式或后台工作程序,或者在服务器中处理并发请求,这里会有一个例外,即所有不同的线程一律前行。操作系统的任务计划程序将确保每个线程均获得公平的共享资源。但这一点对于并行编程并无帮助。如果您感兴趣的是编写将用于新硬件系统的应用程序,它能发挥的作用就更为有限。
如果您想从免费午餐中受益,即通过硬件升级使软件的性能更好,则需要让更多现有的并行功能可以在将来继续发挥功效。在此,我将使用“任务”这一术语取代线程,来强调并行实施中的转变以及我的思路:鼓励应对并行编程的开发人员将问题分解为更多的任务。
并行编程系统的实现应该能根据需要将这些任务映射给系统线程和处理器。只有为数不多的程序员发现,从操作系统取得系统资源并在进程中进行管理以便有效执行并行程序的方式有了巨大的变化。它就象一个线程池,但侧重于将应用程序中的并行机会与当前硬件的可用资源相搭配,而不只是按并行程序员的指令管理线程。
在并发编程中(尤其是服务器),大部分困难源自使用锁等工具协调长时间运行线程对共享变量的访问。如转为具备任务的并行编程,可以使用一个新概念。例如,在任务 A 后面运行一个任务 B,并提供基本协调元素对其加以说明。这样程序员就可以考虑为工作制订计划。通常,这一计划会从本质上配合程序的算法结构,并从并行编程抽象的结构化使用中反映出来。程序抽象与并行算法间的良好配合能极大地减少对传统并发机制的需求(如锁和事件),并可避免许多并发编程的风险(但不能完全消除)。
接下来,我将说明一些并行编程的主要方法并通过正在开发的抽象展示其使用。我还会特别使用 C# 展示 C++ 并行模式库 (PPL) 和 .NET 并行扩展(网址为 )。
结构化多线程
人们处理问题时最常用的模式是先分割再解决:使用定义良好的交互将一个大问题分解为多个小问题,这些问题可单独解决,然后将结果汇总,从而解决原始问题。无论是大型公司的风险,还是邻居的日常琐事,它们都使用这一技术解决问题。由这一观念带动的应用程序也顺理成章的成为了并行编程的基础。
结构化多线程指提供并行模式的顺序语句,它的块呈结构化。例如,一条采用顺序语法的复合语句 { A; B; },原本先求 A 的值,再求 B 的值,现在成为了一个并行语句,A 和 B 可以同时求值。但整个构造并未完成,控制继续转到下一个构造,直到两项子任务全部完成为止。这是一个旧概念,一直被视为 Cobegin 语句有时也称为“派生-联结并行性”以突出结构。相同的基本观点也适用于循环,其中每个迭代均定义一个任务,该任务与其他迭代同时计算。所有迭代均完成后,并行循环即告结束。
著名的 Qu