1.1.2 并行程序设计和多核程序设计
在传统的顺序式代码中,指令一条接着一条运行,这种方式并不能发挥多内核的优势,因为顺序指令只能运行在一个可用内核上。使用Visual C# 2010编写的顺序代码并不能发挥多核的优势,除非利用.NET Framework 4所提供的新功能将任务分解到多个内核上。对于既有的顺序代码来说,并没有一种自动并行化的方法。
并行程序设计是程序设计的一种形式,以这种形式编写的代码能够充分利用底层硬件所提供的并行执行能力。并行程序设计能够在同一时刻运行很多条指令。如前所述,目前存在很多种不同的并行架构,而对这些架构进行详细分析需要完整的一本专著才行。
多核程序设计也是程序设计的一种形式,以这种形式编写的代码能够充分利用多个执行内核并行运行很多条指令。多核和多处理器计算机在一台计算机上提供了多个处理内核。因此,其目标在于通过将任务分布在多个可用内核上完成,以达到事半功倍的效果。
现代处理器可以在多个数据上执行相同的指令,Michael J. Flynn在他1966年提出的 Flynn分类法中将这种方式分类为单指令多数据(Single Instruction, Multiple Data,SIMD)。通过这种方式,可以充分利用这些向量处理器来减少某些算法的执行时间。
本书深入探讨了两类并行程序设计:共享内存的多核程序设计和向量处理能力的应用。总体目标是要减少算法的执行时间。这些增加的处理能力还能让您在既有的软件中添加更多功能。
1.2 理解硬件线程和软件线程
多核微处理器带有一个以上的物理内核(physical core)——物理内核是真正独立的处理单元,多个物理内核使得多条指令能够同时并行地运行。为了充分发挥多物理内核的功效,有必要运行多个进程,或者在一个进程内运行多个线程,创建多线程的代码。
然而,每一个物理内核可能会提供多个硬件线程,也称为逻辑内核或逻辑处理器。使用了Intel Hyper-Threading Technology(超线程计技术,HT或HTT)的微处理器在每一个物理内核上提供了多份架构状态。例如,很多带有4个物理内核并使用了HT技术的微处理器在每一个物理内核上提供两份架构状态,从而获得8个硬件线程。这种技术称为对称多线程(simultaneous multithreading,SMT),它通过额外的架构状态在微处理器的指令级别对并行执行进行优化和增强。SMT并不局限于每物理内核两个硬件线程;例如,有的微处理器的物理内核上有4个硬件线程。需要注意,一个硬件线程并不代表一个物理内核。在某些情形下,SMT可以提升多线程代码的性能。后面的章节会列举一些这种性能提升的示例。
Windows中每个运行的程序都是一个进程(process)。每一个进程会创建并运行一个或多个线程,这些线程称为软件线程(software thread),用于区分前面提到的硬件线程。一个进程至少有一个线程,称为主线程(main thread)。操作系统的调度器在所有要运行的进程和线程之间公平地分享可用的处理资源。Windows调度器会给每一个软件线程分配处理时间。当Windows调度器运行在多核微处理器上时,调度器必须从物理内核支持的硬件线程中分配时间给每一个需要运行指令的软件线程。打一个比方,可以将每一个硬件线程想象为一条泳道,而将软件线程想象为游泳者。