首页 文章

OpenMP 4.0 - GCC 5.2.0 - 重叠设备和主机任务执行

提问于
浏览
4

我试图测试一个非常简单的程序,通过OpenMP 4.0指令使用gcc 5卸载功能 . 我的目标是编写一个两个独立的任务程序,其中一个任务在加速器(即Intel MIC仿真器)上执行,另一个任务在CPU上同时执行 .

这是代码:

#include <omp.h>
#include <stdio.h>

#define limit 100000

int main(int argc, char** argv)
{
    int cpu_prime, acc_prime;

    #pragma omp task shared(acc_prime)
    {
            #pragma omp target map(tofrom: acc_prime)
            {
                    printf("mjf-dbg >> acc computation\n");
                    int i, j;
                    acc_prime=0;
                    for(i=0; i<limit; i++){
                            for(j=2; j<=i; j++){
                                    if(i%j==0)
                                            break;
                            }
                            if(j==i)
                                    acc_prime = i;
                    }
                    printf("mjf-dbg << acc computation\n");
            }
    }

    #pragma omp task shared(cpu_prime)
    {
            int i, j;
            cpu_prime=0;
            printf("mjf-dbg >> cpu computation\n");
            for(i=0; i<limit; i++){
                    for(j=2; j<=i; j++){
                            if(i%j==0)
                                    break;
                    }
                    if(j==i)
                            cpu_prime = i;
            }
            printf("mjf-dbg << cpu computation\n");
    }

    #pragma omp taskwait

    printf("cpu prime: %d \n", cpu_prime);
    printf("gpu prime: %d \n", acc_prime);

}

使用此代码,我期待以下执行流程:

  • 主线程(MT)遇到第一个显式任务区域,绑定到该任务并开始执行 .

  • 遇到目标指令,MT将目标块卸载到加速器并到达调度点

  • MT返回隐式任务区域

  • MT遇到第二个显式任务区域,绑定到该任务并开始执行 .

  • MT与卸载到加速器设备的计算并行地执行主机上的计算 .

  • MT返回隐式任务区域并到达由taskwait指令引起的调度点

  • MT返回到第一个显式任务区域,等待卸载块的结束 .

编译和运行:

gcc -fopenmp -foffload="-march=knl" overlap.c -o overlap
OFFLOAD_EMUL_RUN="sde -knl --" ./overlap

输出:

mjf-dbg >> acc computation
mjf-dbg << acc computation
mjf-dbg >> cpu computation
mjf-dbg << cpu computation
cpu prime: 99991 
gpu prime: 99991

这不是我期望的输出,因为这意味着主线程在调度主机任务之前正在等待卸载计算完成 . 相反,我正在寻找这样的东西:

mjf-dbg >> acc computation
mjf-dbg >> cpu computation
mjf-dbg << cpu computation
mjf-dbg << acc computation
cpu prime: 99991 
gpu prime: 99991

卸载仿真器工作正常,因为在执行期间,我可以看到_offload_target进程在程序执行目标块时将达到100%的CPU使用率 .

所以问题是:有没有人知道为什么这两个任务被序列化而不是并行执行(一个在主机进程上,另一个在_offload_target仿真过程中)?

1 回答

  • 1

    这里有一个比卸载更基本(也更简单)的问题 - 你的任务不在并行区域 .

    OpenMP tasks have to be in a parallel region,即使它们通常嵌入 omp single 中 .

    所以这:

    #include <stdio.h>
    #include <unistd.h>
    
    int main(int argc, char** argv)
    {
    
    #pragma omp task 
        {
            printf("task 1 starts\n");
            sleep(3);
            printf("task 1 ends\n");
        }
    
    #pragma omp task 
        {
            printf("task 2 starts\n");
            sleep(1);
            printf("task 2 ends\n");
        }
    
        return 0;
    }
    

    连续运行任务:

    $ gcc -fopenmp brokentasks.c -o brokentasks
    $ export OMP_NUM_THREADS=2
    
    $ ./brokentasks 
    task 1 starts
    task 1 ends
    task 2 starts
    task 2 ends
    

    而将任务放在一个平行的区域,如下所示:

    #include <stdio.h>
    #include <unistd.h>
    
    int main(int argc, char** argv)
    {
    
    #pragma omp parallel
    #pragma omp single
        {
    #pragma omp task 
            {
                printf("task 1 starts\n");
                sleep(3);
                printf("task 1 ends\n");
            }
    
    #pragma omp task 
            {
                printf("task 2 starts\n");
                sleep(1);
                printf("task 2 ends\n");
            }
        }
    
    }
    

    按预期工作

    $ gcc -fopenmp tasks.c -o tasks
    jdursi@odw-jdursi:~/tmp$ ./tasks
    task 2 starts
    task 1 starts
    task 2 ends
    task 1 ends
    

相关问题