OpenMP single指令内定义task出现多线程执行的原因咨询
现象原因
该现象不是#pragma omp single指令失效,本质是对OpenMP的指令作用边界、task任务调度规则的理解偏差:
#pragma omp single的约束范围仅覆盖它直接绑定的结构化代码块,也就是你代码中负责生成task的for循环段。这部分逻辑确实只会由并行域中的某一个线程执行,你可以观察for循环内、task定义外的printf("%d--->%d\n",omp_get_thread_num(),t);输出,打印的线程号永远唯一,完全符合single指令的预期行为。- 你观察到多线程执行的代码段,是
#pragma omp task包裹的任务块,这部分逻辑本来就不受single指令约束:- OpenMP中
#pragma omp task定义的代码块是独立可调度的任务单元,任务生成后会进入并行域的全局任务队列,和生成它的线程没有绑定关系。 - 并行域内未进入single块的其余线程不会空等single块执行结束,会自动通过任务窃取机制从全局队列拉取任务执行;执行single块的线程在生成任务的间隙、或是single块运行到末尾隐式屏障时,也会参与任务调度执行。
- 你贴出的出现多线程执行的第一段代码片段,恰好属于task块的内部逻辑,这部分被多个线程调度执行是OpenMP任务模型的正常表现,和single指令的作用不存在冲突。
- OpenMP中
验证提示:如果给single指令加上
nowait子句取消末尾隐式屏障,执行完single块的线程会更早参与任务调度,多线程执行task的现象会更明显。如果要求所有计算逻辑只由单个线程执行,直接把计算代码写在single块内即可,不要用task构造包裹。
内容的提问来源于stack exchange,提问作者VC_Vish
相关产品推荐
相关产品推荐

