OpenMP: OpenMP任务划分与调度
2013-04-16 10:34
447 查看
这一片介绍OpenMP的任务划分与调度,还是以代码说明。关于任务划分和调度的介绍这里也省略了。
------------------------ 系统分配任务,static --------------------------
threadnum=0, c[0]=0
threadnum=0, c[1]=2
threadnum=0, c[2]=4
threadnum=0, c[6]=12
threadnum=0, c[7]=14
threadnum=0, c[8]=16
threadnum=0, c[12]=4
threadnum=0, c[13]=6
threadnum=0, c[14]=8
threadnum=1, c[3]=6
threadnum=0, c[18]=16
threadnum=1, c[4]=8
threadnum=0, c[19]=18
threadnum=1, c[5]=10
threadnum=1, c[9]=18
threadnum=1, c[10]=0
threadnum=1, c[11]=2
threadnum=1, c[15]=10
threadnum=1, c[16]=12
threadnum=1, c[17]=14
c[0]=0 c[1]=2 c[2]=4 c[3]=6 c[4]=8 c[5]=10 c[6]=12 c[7]=14 c[8]=16 c[9]=18 c[10]=0 c[11]=2 c[12]=4 c[13]=6 c[14]=8 c[15]=10 c[16]=12 c[17]=14 c[18]=16 c[19]=18
------------------------ 系统分配任务,dynamic --------------------------
threadnum=0, c[0]=0
threadnum=1, c[3]=6
threadnum=0, c[1]=2
threadnum=1, c[4]=8
threadnum=0, c[2]=4
threadnum=1, c[5]=10
threadnum=0, c[6]=12
threadnum=1, c[9]=18
threadnum=0, c[7]=14
threadnum=1, c[10]=0
threadnum=0, c[8]=16
threadnum=1, c[11]=2
threadnum=0, c[12]=4
threadnum=1, c[15]=10
threadnum=0, c[13]=6
threadnum=1, c[16]=12
threadnum=0, c[14]=8
threadnum=1, c[17]=14
threadnum=0, c[18]=16
threadnum=0, c[19]=18
c[0]=0 c[1]=2 c[2]=4 c[3]=6 c[4]=8 c[5]=10 c[6]=12 c[7]=14 c[8]=16 c[9]=18 c[10]=0 c[11]=2 c[12]=4 c[13]=6 c[14]=8 c[15]=10 c[16]=12 c[17]=14 c[18]=16 c[19]=18
------------------------ 系统分配任务,guided --------------------------
threadnum=0, c[0]=0
threadnum=1, c[4]=8
threadnum=0, c[1]=2
threadnum=1, c[5]=10
threadnum=0, c[2]=4
threadnum=1, c[6]=12
threadnum=0, c[3]=6
threadnum=1, c[7]=14
threadnum=0, c[10]=0
threadnum=1, c[8]=16
threadnum=0, c[11]=2
threadnum=1, c[9]=18
threadnum=0, c[12]=4
threadnum=1, c[13]=6
threadnum=0, c[16]=12
threadnum=1, c[14]=8
threadnum=0, c[17]=14
threadnum=1, c[15]=10
threadnum=0, c[18]=16
threadnum=1, c[19]=18
c[0]=0 c[1]=2 c[2]=4 c[3]=6 c[4]=8 c[5]=10 c[6]=12 c[7]=14 c[8]=16 c[9]=18 c[10]=0 c[11]=2 c[12]=4 c[13]=6 c[14]=8 c[15]=10 c[16]=12 c[17]=14 c[18]=16 c[19]=18
------------------------ 手动分配任务,方法一 --------------------------
threadnum=0, c[0]=0
threadnum=1, c[11]=2
threadnum=0, c[1]=2
threadnum=1, c[12]=4
threadnum=0, c[2]=4
threadnum=0, c[3]=6
threadnum=0, c[4]=8
threadnum=0, c[5]=10
threadnum=1, c[13]=6
threadnum=1, c[14]=8
threadnum=0, c[6]=12
threadnum=1, c[15]=10
threadnum=0, c[7]=14
threadnum=0, c[8]=16
threadnum=1, c[16]=12
threadnum=0, c[9]=18
threadnum=1, c[17]=14
threadnum=0, c[10]=0
threadnum=1, c[18]=16
threadnum=1, c[19]=18
c[0]=0 c[1]=2 c[2]=4 c[3]=6 c[4]=8 c[5]=10 c[6]=12 c[7]=14 c[8]=16 c[9]=18 c[10]=0 c[11]=2 c[12]=4 c[13]=6 c[14]=8 c[15]=10 c[16]=12 c[17]=14 c[18]=16 c[19]=18
------------------------ 手动分配任务,方法二 -------------------------
threadnum=0, c[0]=0
threadnum=1, c[1]=2
threadnum=0, c[2]=4
threadnum=1, c[3]=6
threadnum=0, c[4]=8
threadnum=1, c[5]=10
threadnum=0, c[6]=12
threadnum=1, c[7]=14
threadnum=0, c[8]=16
threadnum=1, c[9]=18
threadnum=0, c[10]=0
threadnum=1, c[11]=2
threadnum=0, c[12]=4
threadnum=1, c[13]=6
threadnum=0, c[14]=8
threadnum=1, c[15]=10
threadnum=0, c[16]=12
threadnum=1, c[17]=14
threadnum=0, c[18]=16
threadnum=1, c[19]=18
c[0]=0 c[1]=2 c[2]=4 c[3]=6 c[4]=8 c[5]=10 c[6]=12 c[7]=14 c[8]=16 c[9]=18 c[10]=0 c[11]=2 c[12]=4 c[13]=6 c[14]=8 c[15]=10 c[16]=12 c[17]=14 c[18]=16 c[19]=18
// distribute tasks.cpp : 定义控制台应用程序的入口点。 // #include <stdio.h> #include <omp.h> int main(int argc, char* argv[]) { const int N = 20; int a = {0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9}; int b = {0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9}; int c ; /* 工作量的划分与调度有3种方式: 1、静态:schedule (static [,chunk]),比较适合每次迭代的工作量相近(主要指工作所需时间)的情况。 把循环的迭代按照每x次(x=chunk)迭代分为一块,这样你的总工作量就被划分成了n/x块(n为迭代次数、循环次数), 然后将这些块按照轮转法依次分配给各个线程。举个例子:比如我们有100次迭代, x=chunk=4,那么我们的工作就被分为25块,假设我们有2个线程可以做工作,那么线程1分到的块是 1,3,5,7....,25,线程2分到的块是2,4,6,...,24; 2、动态:schedule (dynamic [,chunk]),比较适合每次迭代的工作量非常不确定的情况。 迭代分块方法同上,但是工作块被放到一个队列中,每个线程每次拿一块,做好了才能到队列里去拿下一块; 3、Guided:schedule (guided [,chunk]),类似动态方式,但是队列相关的开销会比动态方式小 这个方式是动态方式的改进。在这个方式里,分块的x是不固定的,一开始块的大小(x)比较大,随着剩余工作量的减小, 块的大小也随之变小。 4、实时:schedule (runtime [,chunk]),根据系统设置来定。 */ printf("\n------------------------ 系统分配任务,static --------------------------\n"); #pragma omp parallel for schedule(static, 3) // 每一块是3个任务,块按照轮转法依次分配给各个线程,一次性分配完 for(int i=0;i<N;i++) { c[i] = a[i] + b[i]; printf("threadnum=%d, c[%d]=%d\n", omp_get_thread_num(), i, c[i]); } for (int i=0;i<N;i++) { printf("c[%d]=%d\t", i, c[i]); c[i] = 0; } printf("\n------------------------ 系统分配任务,dynamic -------------------------\n"); #pragma omp parallel for schedule(dynamic, 3) // 每一块是3个任务,有个任务块队列,线程每一次从队列里获取一个任务块,执行完再取下一个,所 // 以获得的块号是无序的 for(int i=0;i<N;i++) { c[i] = a[i] + b[i]; printf("threadnum=%d, c[%d]=%d\n", omp_get_thread_num(), i, c[i]); } for (int i=0;i<N;i++) { printf("c[%d]=%d\t", i, c[i]); c[i] = 0; } printf("\n------------------------ 系统分配任务,guided --------------------------\n"); #pragma omp parallel for schedule(guided, 3) // 每一块是3个任务,有个任务块队列,随着任务的减少,块的大小也在减小 for(int i=0;i<N;i++) { c[i] = a[i] + b[i]; printf("threadnum=%d, c[%d]=%d\n", omp_get_thread_num(), i, c[i]); } for (int i=0;i<N;i++) { printf("c[%d]=%d\t", i, c[i]); c[i] = 0; } /* 自己手动分配任务(类似与划分与调度策略的static,轮转分配) * 第一种是每个线程分配的块里的任务是连续的, id*(N/Nthrds)-->(id+1) * (N / Nthrds); * 第二种每个线程分配的块里的任务是分散的,第id个,第id+Nthrrds个,第id+2*Nthrds。。。只到 id+m*Nthrds>=N,。 * 这两种思想的区别值得借鉴。 */ // 方法一 printf("\n------------------------ 手动分配任务,方法一 ------------------\n"); #pragma omp parallel { int i, istart, iend; int Nthrds = omp_get_num_threads(), id = omp_get_thread_num(); if (N/Nthrds == 0) { istart = id * (N / Nthrds); // 每个线程都完成N/Nthrds个任务,就是将N个任务平均分给Nthrds个线程,最后一个线程可能不足 // N/Nthrds个任务 iend = (id+1) * (N / Nthrds); } else{ istart = id * (N/Nthrds + 1); // 每个线程都完成N/Nthrds + 1个任务,最后一个线程可能不足N/Nthrds + 1个任务。或者可以每个线 // 程完成N/Nthrds个,最后一个线程多完成剩余的 iend = (id+1) * (N/Nthrds + 1); } for(i=istart; i<iend && i<N; i++) { c[i] = a[i] + b[i]; printf("threadnum=%d, c[%d]=%d\n", id, i, c[i]); } } for (int i=0;i<N;i++) { printf("c[%d]=%d\t", i, c[i]); c[i] = 0; } printf("\n------------------------ 手动分配任务,方法二 -------------------------\n"); // 方法二 #pragma omp parallel { int i, istart, iend; int Nthrds = omp_get_num_threads(), id = omp_get_thread_num(); iend = N; for(i=id; i<iend; i+=Nthrds) // 每个线程一次完成第id个任务,第id+Nthrrds个,第id+2*Nthrds。。。只到id+m*Nthrds>=N { c[i] = a[i] + b[i]; printf("threadnum=%d, c[%d]=%d\n", id, i, c[i]); } } for (int i=0;i<N;i++) { printf("c[%d]=%d\t", i, c[i]); c[i] = 0; } return 0; }下面是输出,系统设置为2个线程
------------------------ 系统分配任务,static --------------------------
threadnum=0, c[0]=0
threadnum=0, c[1]=2
threadnum=0, c[2]=4
threadnum=0, c[6]=12
threadnum=0, c[7]=14
threadnum=0, c[8]=16
threadnum=0, c[12]=4
threadnum=0, c[13]=6
threadnum=0, c[14]=8
threadnum=1, c[3]=6
threadnum=0, c[18]=16
threadnum=1, c[4]=8
threadnum=0, c[19]=18
threadnum=1, c[5]=10
threadnum=1, c[9]=18
threadnum=1, c[10]=0
threadnum=1, c[11]=2
threadnum=1, c[15]=10
threadnum=1, c[16]=12
threadnum=1, c[17]=14
c[0]=0 c[1]=2 c[2]=4 c[3]=6 c[4]=8 c[5]=10 c[6]=12 c[7]=14 c[8]=16 c[9]=18 c[10]=0 c[11]=2 c[12]=4 c[13]=6 c[14]=8 c[15]=10 c[16]=12 c[17]=14 c[18]=16 c[19]=18
------------------------ 系统分配任务,dynamic --------------------------
threadnum=0, c[0]=0
threadnum=1, c[3]=6
threadnum=0, c[1]=2
threadnum=1, c[4]=8
threadnum=0, c[2]=4
threadnum=1, c[5]=10
threadnum=0, c[6]=12
threadnum=1, c[9]=18
threadnum=0, c[7]=14
threadnum=1, c[10]=0
threadnum=0, c[8]=16
threadnum=1, c[11]=2
threadnum=0, c[12]=4
threadnum=1, c[15]=10
threadnum=0, c[13]=6
threadnum=1, c[16]=12
threadnum=0, c[14]=8
threadnum=1, c[17]=14
threadnum=0, c[18]=16
threadnum=0, c[19]=18
c[0]=0 c[1]=2 c[2]=4 c[3]=6 c[4]=8 c[5]=10 c[6]=12 c[7]=14 c[8]=16 c[9]=18 c[10]=0 c[11]=2 c[12]=4 c[13]=6 c[14]=8 c[15]=10 c[16]=12 c[17]=14 c[18]=16 c[19]=18
------------------------ 系统分配任务,guided --------------------------
threadnum=0, c[0]=0
threadnum=1, c[4]=8
threadnum=0, c[1]=2
threadnum=1, c[5]=10
threadnum=0, c[2]=4
threadnum=1, c[6]=12
threadnum=0, c[3]=6
threadnum=1, c[7]=14
threadnum=0, c[10]=0
threadnum=1, c[8]=16
threadnum=0, c[11]=2
threadnum=1, c[9]=18
threadnum=0, c[12]=4
threadnum=1, c[13]=6
threadnum=0, c[16]=12
threadnum=1, c[14]=8
threadnum=0, c[17]=14
threadnum=1, c[15]=10
threadnum=0, c[18]=16
threadnum=1, c[19]=18
c[0]=0 c[1]=2 c[2]=4 c[3]=6 c[4]=8 c[5]=10 c[6]=12 c[7]=14 c[8]=16 c[9]=18 c[10]=0 c[11]=2 c[12]=4 c[13]=6 c[14]=8 c[15]=10 c[16]=12 c[17]=14 c[18]=16 c[19]=18
------------------------ 手动分配任务,方法一 --------------------------
threadnum=0, c[0]=0
threadnum=1, c[11]=2
threadnum=0, c[1]=2
threadnum=1, c[12]=4
threadnum=0, c[2]=4
threadnum=0, c[3]=6
threadnum=0, c[4]=8
threadnum=0, c[5]=10
threadnum=1, c[13]=6
threadnum=1, c[14]=8
threadnum=0, c[6]=12
threadnum=1, c[15]=10
threadnum=0, c[7]=14
threadnum=0, c[8]=16
threadnum=1, c[16]=12
threadnum=0, c[9]=18
threadnum=1, c[17]=14
threadnum=0, c[10]=0
threadnum=1, c[18]=16
threadnum=1, c[19]=18
c[0]=0 c[1]=2 c[2]=4 c[3]=6 c[4]=8 c[5]=10 c[6]=12 c[7]=14 c[8]=16 c[9]=18 c[10]=0 c[11]=2 c[12]=4 c[13]=6 c[14]=8 c[15]=10 c[16]=12 c[17]=14 c[18]=16 c[19]=18
------------------------ 手动分配任务,方法二 -------------------------
threadnum=0, c[0]=0
threadnum=1, c[1]=2
threadnum=0, c[2]=4
threadnum=1, c[3]=6
threadnum=0, c[4]=8
threadnum=1, c[5]=10
threadnum=0, c[6]=12
threadnum=1, c[7]=14
threadnum=0, c[8]=16
threadnum=1, c[9]=18
threadnum=0, c[10]=0
threadnum=1, c[11]=2
threadnum=0, c[12]=4
threadnum=1, c[13]=6
threadnum=0, c[14]=8
threadnum=1, c[15]=10
threadnum=0, c[16]=12
threadnum=1, c[17]=14
threadnum=0, c[18]=16
threadnum=1, c[19]=18
c[0]=0 c[1]=2 c[2]=4 c[3]=6 c[4]=8 c[5]=10 c[6]=12 c[7]=14 c[8]=16 c[9]=18 c[10]=0 c[11]=2 c[12]=4 c[13]=6 c[14]=8 c[15]=10 c[16]=12 c[17]=14 c[18]=16 c[19]=18
相关文章推荐
- OpenMP学习之--任务划分与调度(代码示例)
- OpenMP中的任务调度
- OpenMP中的任务调度
- OpenMP中的任务调度
- OpenMP中的任务调度
- OpenMP中的任务调度
- OpenMP中的任务调度
- OpenMP中的任务调度
- OpenMP中的任务调度
- OpenMP中的任务调度
- OpenMP中的任务循环调度和分块
- OpenMP编程的任务调度控制
- OpenMP中的任务调度
- OpenMP中的任务调度
- OpenMP 中的线程任务调度
- openmp 任务调度 for schedule static dynamic guided runtime
- OpenMP中的任务调度
- OpenMP中的任务调度
- OpenMP 中的线程任务调度
- OpenMP中的任务调度