Task 如何正确生成/恢复OpenMP未绑定的任务?

Task 如何正确生成/恢复OpenMP未绑定的任务?,task,openmp,Task,Openmp,我编写了一个小型C程序来评估OpenMP在任务出现空闲时间(例如,等待通信数据)时向另一个任务让步的能力: #包括 #包括 #包括 #定义NTASKS 10 双壁时钟时间(无效){ 结构时间值t; gettimeofday(&t,NULL); 返回(双倍)(t.tv_sec+t.tv_usec/1000000); } 无效打印状态(字符*状态、int taskNum、int threadNum){ #pragma omp临界(打印状态) { int i; 对于(i=0;i

我编写了一个小型C程序来评估OpenMP在任务出现空闲时间(例如,等待通信数据)时向另一个任务让步的能力:

#包括
#包括
#包括
#定义NTASKS 10
双壁时钟时间(无效){
结构时间值t;
gettimeofday(&t,NULL);
返回(双倍)(t.tv_sec+t.tv_usec/1000000);
}
无效打印状态(字符*状态、int taskNum、int threadNum){
#pragma omp临界(打印状态)
{
int i;
对于(i=0;i
我使用了英特尔C编译器17.0.4。以下是使用3个线程运行的输出:

thread 0 is master

 00  01  02  03  04  05  06  07  08  09 
 r1 
                                     r0 
     r2 
 s1 
                                     s0 
     s2 
                                 r0 
 c1 
     c2 
                                 s0 
                             r0 
         r1 
             r2 
                             s0 
                         r0 
         s1 
             s2 
                         s0 
                     r0 
         c1 
             c2 
                     s0 
                 r0 
                 s0 
                 c0 
                     c0 
                         c0 
                             c0 
                                 c0 
                                     c0
线程1和线程2根本不屈服,但它们坚持执行分配的任务。我还希望线程1和线程2继续执行挂起的未绑定任务04。。。09,但这些仅由主线程0处理,而其他线程处于空闲状态


是否必须以不同的方式发布或生成任务,或者Intel的OpenMP运行时(尚未)无法处理此问题?顺便说一句,GNU gcc 4.9.2根本不能从任务中获得收益。

我认为您的代码很好,这是一个实现问题。事实上,在LLVM OpenMP实现中—这与Intel的非常相关—修复了您的问题。在我的测试中,clang当前的
libiomp5.so
(从主干构建)与
ICC17.0.4
兼容,只需设置
LD\u LIBRARY\u路径
,即可产生所需的结果

thread 0 is master

 00  01  02  03  04  05  06  07  08  09 
                                     r0 
 r2 
     r1 
                                     s0 
                                 r0 
 s2 
         r2 
     s1 
             r1 
                                 s0 
                             r0 
         s2 
                 r2 
             s1 
                     r1 
                             s0 
                         r0 
                 s2 
                     s1 
                 c2 
                         s0 
                     c1 
                         c0 
         c2 
             c1 
                             c0 
 c2 
     c1 
                                 c0 
                                     c0 
我还可以确认gcc根本不会让步,但还没有详细研究

我不知道更改是否以及何时会合并到Intel提供的库中

更新:你是对的,行为仍然不是最佳的。通过简单地查看代码,似乎
libiomp
支持绑定任务的概念,但在
taskwait
期间不重新请求任务,而是只执行另一个任务并在堆栈上保留挂起任务的上下文。我怀疑一个合适的支持需要更多的编译器支持(某种类型的延续),而不仅仅是生成库调用


同样,您所做的一切都是正确的,但是编译器/运行时不够复杂,无法支持标准允许的内容(行为完全符合标准)。还请注意,对于所描述的
libiomp
的当前行为,任务甚至不需要解开,因为到目前为止它们只是队列。除了拆分/链接任务之外,似乎没有一种简单的方法可以满足您的需求。

欢迎使用SO。这是一个多么好的第一个问题,包含了复制和回答它所需的一切!谢谢你的回答。然而,我认为运行时仍然没有真正做它应该做的事情。当然,线程1和线程2的任务现在显然是可暂停的,但所有任务似乎仍然是绑定的,而不是未绑定的。至少线程1或2应恢复任务09。这仍然由主线程0连续恢复。编辑示例以获得不均匀的工作负载应该强调这种行为。是的,你是对的。我在更新我的帖子时讨论了这个问题。不幸的是,我不知道如何模拟真正可中断/不可中断的任务。“英特尔C编译器18.0.1”的运行时给出的结果与您在clang的运行时中观察到的结果类似。然而,这些任务似乎仍然是捆绑在一起的,但至少对非主线程产生了效果。我将与英特尔技术支持部门联系,以了解将来是否会出现未绑定的任务。