高性能计算中并行的概念理解

来源:互联网 发布:苹果机下载不了软件 编辑:程序博客网 时间:2024/05/21 04:43
 

高性能计算中并行的概念理解

分类: 并行计算高性能计算HPC — General 932人阅读 评论(0) 收藏 举报
编译器编程parallel优化formsvector

要理解并行编程,首先要从并行的理解开始。

(1)从Wiki中并行编程的解释说起

Wiki是个好东西,包含了很多专业术语的解释,关键的是,除了解释,wiki还是一个好文档。

Paralle Programming(并行编程/并行计算)Wiki:http://en.wikipedia.org/wiki/Parallel_programming

Parallel computing is a form of computation in which many calculations are carried out simultaneously,[1] operating on the principle that large problems can often be divided into smaller ones, which are then solved concurrently ("in parallel"). There are several different forms of parallel computing: bit-level, instruction level, data, and task parallelism. Parallelism has been employed for many years, mainly in high-performance computing.

这里要讨论的就是上面的这句话中加粗的部分的内容。要理解好并行编程,首先需要理解并行编程的形式。并行编程的形式包括:

bit-level parallelism:位级别的并行,是基于处理器的字长不断增加的基础上,就比较容易理解了。处理器的字长不断增加,并行度自然增加。(http://en.wikipedia.org/wiki/Bit-level_parallelism)

instruction level parallelism(ILP):指令级并行,是指处理器能同时处理多条指令。

data level parallelism(DLP):数据集并行,是指处理器能同时处理多条数据。

task level parallelism(TLP):任务级并行,我见过更多的是称为Thread-level parallelism(TLP),即线程级并行。

下面就这些并行的概念进行进一步分析,这些并行的方式,特别是BLP、ILP和DLP本身都是和处理器微架构有关的内容,从微架构的角度,才能更理解并行。线程级并行可以是软件也可以有硬件支持。

(2)并行的两大分类

既然提到了微架构,就不得提一下并行的两大分类,微架构中经常将并行分为两大类:时间并行和空间并行。时间并行指的是流水线并行,空间并行包括指令并行、数据并行和线程并行。

更多关于以微架构的角度讨论这几个并行,参考相关的书籍,入门推荐《大话处理器》。

(3)指令级并行

所谓指令级并行,是指处理器能同时运行多条指令。

一般而言,如果程序中相邻的一组指令是相互独立的,即不竞争同一个功能部件、不相互等待对方的运算结果、不访问同一个存储单元,那么它们就可以在处理器内部并行地执行。

超标量(Superscalar)技术 和 超长指令字(Very Long Instruction Word, VLIW)技术是目前最基本的两类指令级并行技术。前者的特点是采用普通的指令,设置多条并行工作的指令流水线;后者的特点是:将若干条普通指令组装在一起,形成一条“超级指令”。这条“超级指令”包含多个不同操作码,这些操作码分别处理不同的操作数。对应这些操作码,一一对应地设置相应的功能部件。这样,只要取指令一次、分析指令一次,VLIW 技术就可以实现对多个不同的操作数,同时进行不同的处理/计算。目前,主流的微处理器都采用了超标量技术。

当然,现代处理器有很多能帮助其进行指令并行的设计,比如乱序执行、寄存器重命名等技术。指令级命令,需要依赖于具体的硬件支持,以及编译器支持。通常,我们需要依赖编译器的优化来生成指令级并行的代码,当然,对于有些情况,编译器需要我们的帮助,更容易生成指令级并行的代码,具体需要根据编译器的实现。

参考http://www.docin.com/p-148703990.html介绍用软件方法开发指令级并行代码,其实,其分析的正是编译器生成指令级并行的例子(流水线调度和循环展开等)。

(3)数据级并行

所谓数据级并行,是指处理器能同时运行多条数据。数据并行需要从SIMD、MMX、SSE等谈起了。

SIMD:single instruction multiple data,单指令多数据,即同一操作会重复处理多个数据,一条语句处理多个数据的指令,就是SIMD指令。SIMD指令的出现是从多媒体时代开始的,由于多媒体中很多数据的处理就是SIMD的模型,所以,诞生了SIMD指令。现在的高性能处理器都支持SIMD指令,Intel从1996年开始增加MMX(MultiMedia eXtensions)指令集(也即SIMD指令),后来逐步增加了SSE(Streaming SIMD Extensions)、SSE2、SSE3、SSSE3、SSE4.1、SSE4.2、AVX(Advanced Vector Extensions)指令集。所以说,数据级并行,也是依靠处理器的指令集完成了。数据并行的模型包括垂直计算形式、水平计算形式、标量计算模式,图解可参考《大话处理器》的相关内容。

简单的理解,向量a[N],b[N],c[N],那么

1. 垂直计算模式:a[i] op b[i] = c[i]

2. 水平计算模式:a[i] op a[i+1] = c[i] (前半部分) b[i] op b[i+1] = c[i] (后边部分),这里的前半部分后半部分并不是严格的,得看指令会如何处理,总是,垂直计算方式,操作数来自于不同的源,水平计算方式,操作数可以来自于同一个源。

3. 标量计算模式:a[0] op b[0] = c[0],其余不变。

对于多媒体的计算和科学计算,存在大量类似的计算,所以说SIMD能极大的提高计算性能。

当然,数据并行,比如垂直计算模式,最常见的情况,就是一个for循环了。

for(int i = 0;i< N;i ++) c[i] = a[i] + b[i];

这样的代码就能生成SIMD指令,那么是不是这么一个循环,直接一条指令搞定!当然不是,并行是有限制的,能接受的N不可能无限大!对于不同的指令集,一次数据并行能接受的数据长度是一定的,对于AVX指令集,能接受的长度为256字节。所以,可以对这样的循环进行优化,比如:

for(int i = 0;i < N;i +=4) { c[i] = a[i] + b[i]; c[i+1] = a[i+1] + b[i+1]; c[i+2] = a[i+2] + b[i+2]; c[i+3] = a[i+3] + b[i+3]; }

这样编译器就能很容易的生成SIMD指令(具体需要依赖编译器的实现,这里的4也是一个例子,前提是数组a/b/c的数据元素乘以4为SIMD指令集能接受一次运算的长度)

(4)线程级并行

线程并行是一种更高层的数据并行,是一种分时复用的思想。线程级并行可以依靠操作系统(软件)来完成,但是现在的处理器,硬件也会为线程并行提供帮助,从而提高线程并行的效率。


更多内容,参考《大话处理器》或者其他关于微架构的资料。

只有了解和理解了并行的这些概念,才能更好的理解编译器优化的工作,也就能更好的让我们写出更容易让编译器生成并行化代码的代码。

0 0
原创粉丝点击