OpenMP 调度程序

OpenMP scheduler

我在 OpenMP 中分配任务时遇到问题。 我有下一个代码:

#include <stdio.h>
#include <unistd.h>

int cnttotal = 0;
int cnt1 = 0, cnt2 = 0;

int main()
{
    int i;
    #pragma omp parallel
    #pragma omp single nowait
    for (i = 0; i < 60; i++) {
        if (cnttotal < 1) {
            cnttotal++;
            #pragma omp task
            {
                #pragma omp atomic
                cnt1++;
                usleep(10);
                cnttotal--;
            }
        } else {
            #pragma omp task
            {
                #pragma omp atomic
                cnt2++;
                sleep(1);
            }
        }
    }

printf("cnt1 = %d; cnt2 = %d\n", cnt1, cnt2);

    return 0;
}

什么我没有,cnt1 = 1cnt2 = 59。我认为 OpenMP 调度程序中存在该问题。 或者有什么东西没有抓住。

我的感觉是您混淆了任务实例化和任务的实际执行。 #pragma omp 任务指的是任务的实例化,速度非常快。另一件事是 OpenMP 运行时的空闲线程查找就绪任务列表并执行它。

进入你发布的问题。在这段代码中,一个 运行 线程(比如 T1)进入第一次迭代(i=0),因此它进入第一个 if,然后将 cnttotal 设置为 1 并实例化第一个任务(cnt1)。在该实例化之后,T1 继续实例化剩余的任务,而空闲线程(比如 T2)执行任务 cnt1,这需要大约 10us 并再次将 cnttotal 设置为 0。

所以简而言之,实例化任何任务的线程比任务 cnt1 中的那些 10us 执行得更快。

例如,在我的 Intel(R) Core(TM) i7-2760QM CPU @ 2.40GHz 中,如果我更改代码以便循环运行直到 i = 500 并休眠 1 us(usleep( 1)) 我得到:

cnt1 = 2; cnt2 = 498

这表明任务的实例化非常快。