Parallel Programming Patterns
1.根据设计需求,找出可以并行设计程序的空间
A.找出并发的内容
a) 域分解
b) 任务分解
B.算法结构设计空间
设计出的算法具有:效率,简单,可移植,可测量
C.支持结构
a) 程序结构
SPMD – Same Program Multiple Data
loop parallelism
boss/worker
fork join
b) 数据结构
i. 共享数据
ii. 共享队列
iii. 分布数组
D.落实机器处理空间
2.改进设计
A.任务,数据,部分程序的顺序
B.线程,进程,时间清单
C.源代码的组织,共享数据
D.消息,同步机制,结果
并行任务分析
任务分解
Example
First.嵌套循环中,比如串行执行M*N个时钟
#define N 23
#define M 1000
for (k = 0; k < N; k++)
for (j = 0; j < M; j++)
w_new[k][j] = DoSomeWork(w[k][j], k, j);
Second.转换成一个for循环,串行依然是M*N个时钟
#define N 23
#define M 1000
for (kj = 0; kj < N*M; kj++) {
k = kj / M;
j = kj % M;
w_new[k][j] = DoSomeWork(w[k][j], k, j);
Third.用多线程并行,
#define N 23
#define M 1000
#pragma omp for private(k,j) schedule(static, 500)
动态调度让每一条线程执行通过块大小(chunk-size)(默认为1)指定数量的迭代。当线程执行完交给它的迭代,它就请求再次执行chunk-size次迭代,直到所有迭代结束。显而易见,最后一次迭代可能少于chunk-size次
for (kj = 0; kj < N*M; kj++) {//k,j都是每个线程私有的变量
k = kj / M;
j = kj % M;
w_new[k][j] = DoSomeWork(w[k][j], k, j);
}
#define N 23
#define M 5323
#define numThreads 16
. . .
int start = ((N*M)/numThreads) * myID;
int end = ((N*M)/numThreads) * (myID+1);
. . .
if (myID == (numThreads-1)) end = N*M;
. . .
for (kj = start; kj < end; kj++) { . . . }
#define N 23
#define M 1000
#define numThreads 4
. . .
for (kj = myID; kj < N*M; kj+=numThreads) {
k = kj / M;
j = kj % M;
w_new[k][j] = DoSomeWork(w[k][j], k, j);
}