夏霏 2009.12

Post on 05-Jan-2016

58 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

OpenMP 范例. OpenMP 范例. 夏霏 2009.12. ?. 1. 3. 2. OpenMP. Why OpenMP. CPU 核数扩展性. 方便性. 可移植性. OpenMP 例子. 反依赖的消除 循环依赖的消除 OpenMP 实现流水线. 反依赖的例子. int V[ VSIZE+1 ],i,U[VSIZE+1]; for (i=0; i

TRANSCRIPT

夏霏2009.12

Why OpenMP

1

CPU 核数扩展性

3

可移植性

2

方便性

OpenMP

OpenMP 例子

• 反依赖的消除

• 循环依赖的消除

• OpenMP 实现流水线

反依赖的例子 int V[ VSIZE+1 ],i,U[VSIZE+1];

for (i=0; i<VSIZE+1; i++) {

V[i]= i ;

U[i] = i ;

}

for(i=0;i<VSIZE;i++) U[i] = U[i] + U[i+1];

omp_set_num_threads(NUM_THREADS);

#pragma omp parallel for default(none) shared(V) private(i) schedule(static)

for (i=0; i<VSIZE; i++) {

V[i] = V[i] + V[i+1];}

parallel forOpenMP 指令使用的格式为 # pragma omp 指令 [ 子句 [ 子句 ]…]

parallel for 就是一条指令,“指令” = “ 编译指导语句” private 子句

#pragma omp directive-name [clause, ...] newline

制导指令前缀。对所有的OpenMP 语句都需要这样的前缀。

OpenMP 制导指令。在制导指令前缀和子句之间必须有一个正确的 OpenMP 制导指令。

子句。在没有其它约束条件下,子句可以无序,也可以任意的选择。 这一部分也可以没有。

换行符。表明这条制导语句的终止。

parallel forparallel 指令的用法

parallel 是用来构造一个并行块的,也可以使用其他指令如 for 、 sections 等和它配合使用。

#pragma omp parallel [for | sections] [ 子句 [ 子句 ]…]

{

// 代码}

parallel forfor 指令的使用方法

for 指令则是用来将一个 for 循环分配到多个线程中执行。 for 指令一般可以和 parallel 指令合起来形成 parallel for 指令使用,也可以单独用在 parallel 语句的并行块中。

#pragma omp [parallel] for [ 子句 ]

for 循环语句

parallel for• parallel ,用在一个代码段之前,表示这段代码将被多

个线程并行执行

• for ,用于 for 循环之前,将循环分配到多个线程中并行执行,必须保证每次循环之间无相关性。

• parallel for , parallel 和 for 语句的结合,也是用在一个 for 循环之前,表示 for 循环的代码将被多个线程并行执行。 – SIMD

反依赖的例子"badloop.c "

int V[ VSIZE+1 ],i,U[VSIZE+1];

for (i=0; i<VSIZE+1; i++) {

V[i]= i ;

U[i] = i ;

}

for(i=0;i<VSIZE;i++) U[i] = U[i] + U[i+1];

omp_set_num_threads(NUM_THREADS);

#pragma omp parallel for default(none) shared(V) private(i) schedule(static)

for (i=0; i<VSIZE; i++) {

V[i] = V[i] + V[i+1]; // 先读后写的反依赖关系}

反依赖处理 1

Parallelizing an inner loop with dependences

Backward dependency

for (i=0; i<size-1; i++) {

V[i] = V[i]+V[i+1];

}

Method: Eliminate dependences by duplicating data

Optimization: None, duplicate the full data

对引起反依赖关系的 V[i+1] 采用了数据冗余的作法,引入oldV 数组,从而解决先读后写的反依赖关系。

反依赖处理 1"loopA1.c"

#pragma omp parallel for default(none) shared(V,oldV) private(i) schedule(static)

for (i=0; i<VSIZE; i++) {oldV[i] = V[i] ;}

#pragma omp parallel for default(none) shared(V,oldV) private(i) schedule(static)

for (i=0; i<VSIZE-1; i++) {V[i] = V[i]+oldV[i+1];}

反依赖处理 2

• 采用的边界范围 limitL 和 limitR ,以及边界值 border ;首先,各线程读取各自的border (编号最大的一个线程出外),然后同步。

• 接着,各线程独立更新 limitL ~ limitR – 1 范围内的值,再更新 limitR 的值;再次同步!

反依赖处理 2"loopA2.c"

#pragma omp parallel default(none) shared(V,size) private(id,LimitL,LimitR,border,i)

{

id = omp_get_thread_num();

LimitL = id*size;LimitR = (id+1)*size-1; // 确定边界

if (id != THREADS_NUM-1) border = V[LimitR+1];

#pragma omp barrier

...

反依赖处理 2

... ...

for (i=LimitL; i<LimitR; i++) {

V[i] = V[i] + V[i+1];

}

if (id != THREADS_NUM-1)

V[LimitR] = V[LimitR] + border ;

#pragma omp barrier

barrier ,用于并行区内代码的线程同步,所有线程执行到 barrier 时要停止,直到所有线程都执行到 barrier 时才继续往下执行。

OpenMP 例子

• 反依赖的消除

• 循环依赖的消除

• OpenMP 实现流水线

循环分布变换的例子"dis-err.c"

int a[Iter],b[Iter],c[Iter],d[Iter],f[Iter];

int a1[Iter],b1[Iter],c1[Iter],d1[Iter],f1[Iter];

for(i=0;i<Iter;i++) a[i] = b[i] = c[i] = d[i] = f[i] =i;

for(i=0;i<Iter;i++) a1[i] = b1[i] = c1[i] = d1[i] = f1[i] =i;

循环分布变换的例子 for(i=4;i<Iter-1;i++){

a1[ i ] = b1[ i-2 ] + 1; c1[ i ] = b1[ i-1 ] + f1[ i ]; b1[ i ] = a1[ i-1 ] + 2; d1[ i ] = d1[ i+1] + b1[ i-1]; }

#pragma omp parallel for shared(a,b,c,d,f) private(i) for(i=4;i<Iter-1;i++){

a[ i ] = b[ i-2 ] + 1; c[ i ] = b[ i-1 ] + f [ i ]; b[ i ] = a[ i-1 ] + 2; d[ i ] = d[ i+1 ] + b[ i-1 ]; } //ERROR

循环分布变换的例子

• "dis-ok1.c"– S1: a[ i ] = b[ i-2] + 1;– S2: c[ i ] = b[ i-1] + f[ i ]; – S3: b[ i ] = a[ i-1] + 2; – S4: d[ i ] = d[ i+1] + b[ i-1];

• int old_d[Iter]; // duplicating array-d to avoid anti-dependency

循环分布变换的例子#pragma omp parallel shared(a,b,c,d,old_d,f) private(i){ #pragma omp master for(i=4;i<Iter-1;i++){ a[i] = b[i-2] + 1; // S1 b[i] = a[i-1] + 2; // S3 } // 只有主线程执行循环 S1 和 S3

#pragma omp barrier

/* The Parallel Loop below containing both Statement S2 and S4*/ #pragma omp for for(i=4;i<Iter-1;i++) { c[i] = b[i-1] + f[i] ; // S2 d[i] = old_d[i+1] + b[i-1] ; // S4 } // 消除反依赖后, S2 和 S4 由其他线程并行执行

OpenMP 例子

• 反依赖的消除

• 循环依赖的消除

• OpenMP 实现流水线

使用 OpenMP 实现流水线for (iter=0; iter<numiter; iter++)

{for (i=0; i<size-1; i++){

V[i] = f( V[i], V[i – 1 ] ); } }

流依赖! 内层循环无法直接采用 OMP 制导命令来并行化

for (j=0; j<M; j++)

#pragma omp parallel for default(none) shared(V) private(i) schedule(static)

for (i=1; i<N; i++) V[i] = ( V[i] + V[i-1] ) / 2 ; ERROR

使用 OpenMP 实现流水线鉴于程序的特点,可以施加流水线并行技术。Program a threads pipeline !!并行域,流水线核心:

// Parallel Region // 每个线程进行 M + nthreads 次迭代以完成流水线 M+nthreads-1

1). 拷贝邻居线程的边界数据 border = V[limitL - 1]2). 在更新局部数据前,所有线程同步 barrier

3). 以流水线方式计算局部数据更新3a). 每个线程计算自己的第一个元素的值a[limitL] = ( a[limitL] + border ) / 2;3b). 计算剩余元素的值for (i=limitL+1; i<=limitR; i++) a[i] = ( a[i] + a[i-1] ) / 2;

// 拷贝已更新的边界数据前,所有线程再次同步。之后回到 1)//End of Parallel Region

使用 OpenMP 实现流水线• M = 2 , nthreads = 3• 黑色表示线程 #0 ,红色表示线程 #1 ,黄色表示线程 #2

使用 OpenMP 实现流水线以下为实际程序的在 1 、 2 、 4 、 8 个线程下实际运行结果。登录结点 43 后,可以在 rsh 到结点 28 上(可能负荷轻点):

[alex@node28 omp-demo]$ export OMP_NUM_THREADS=1[alex@node28 omp-demo]$ ./pipe 1000000 1000 1 Threads of 1000 iterations with 1000000 elements = 9.445195 (sec)[alex@node28 omp-demo]$ export OMP_NUM_THREADS=2[alex@node28 omp-demo]$ ./pipe 1000000 1000 2 Threads of 1000 iterations with 1000000 elements = 4.814943 (sec)[alex@node28 omp-demo]$ export OMP_NUM_THREADS=4[alex@node28 omp-demo]$ ./pipe 1000000 1000 4 Threads of 1000 iterations with 1000000 elements = 2.571246 (sec)[alex@node28 omp-demo]$ export OMP_NUM_THREADS=8[alex@node28 omp-demo]$ ./pipe 1000000 1000 8 Threads of 1000 iterations with 1000000 elements = 1.176101 (sec)[alex@node28 omp-demo]$

并行程序设计高性能

计算任务划分 依赖

死锁通讯

延伸阅读

《多核计算与程序设计》作  者: 周伟明 著出 版 社: 华中科技大学出版社

第三章中关于 OpenMP 相关内容

【 1 】

【 2 】 Barbara Chapman , “ How OpenMP is Compiled ”http://cobweb.ecn.purdue.edu/ParaMount/iwomp2008/documents/chapman-underthehood

夏霏2009.12

top related