Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
OpenMP 4.0-GCC 5.2.0-重叠设备和主机任务执行_C_Multithreading_Openmp_Hardware Acceleration_Xeon Phi - Fatal编程技术网

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

OpenMP 4.0-GCC 5.2.0-重叠设备和主机任务执行,c,multithreading,openmp,hardware-acceleration,xeon-phi,C,Multithreading,Openmp,Hardware Acceleration,Xeon Phi,我试图测试一个非常简单的程序,它通过OpenMP 4.0指令使用gcc 5卸载功能。我的目标是编写一个两个独立的任务程序,其中一个任务在加速器(即Intel MIC emulator)上执行,另一个任务在CPU上并发执行 代码如下: #include <omp.h> #include <stdio.h> #define limit 100000 int main(int argc, char** argv) { int cpu_prime, acc_prime

我试图测试一个非常简单的程序,它通过OpenMP 4.0指令使用gcc 5卸载功能。我的目标是编写一个两个独立的任务程序,其中一个任务在加速器(即Intel MIC emulator)上执行,另一个任务在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);

}
输出:

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计算
mjf dbg>cpu计算
mjf dbg>acc计算
mjf dbg>>cpu计算

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

,即使它们通常会嵌入到
omp单曲中

因此:

#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;
}
而将任务放在一个平行区域中,如下所示:

#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一个bug。@杰夫谢谢你的评论,如果没有人能解释我所观察到的行为,我会考虑提交一个bug。你能在真正的硬件上运行这个简单的测试吗(可能是一个仿真问题)?我希望我能做到这一点,但现在我没有机会接触到一台带有真正英特尔麦克风的机器。谢谢你为什么不能在KNC上运行它?用户可以使用很多这样的机器。是的,如果我能有一个真正的KNC,我愿意这样做,目前我必须坚持使用模拟器,因为我没有真正的硬件来测试我的代码:(@Jeff你不能用
-march=pentium
编译一个程序并在KNC上运行,因为KNC需要ELF头中的特殊
e_machine
值(
EM_K1OM
)。谢谢你的回答,但我想说的是,它并没有真正回答我的问题,这完全是关于卸载。当然,如果我将我的任务放在一个至少有2个线程的并行区域内,那么事情就会或多或少地按照预期进行。或多或少!事实上,每个线程都在执行一个任务,因此我看到了预期的输出,但仍然看到了线程的执行卸载任务正在等待设备完成其作业。这对我来说是意外的,线程应该在目标指令之后到达一个调度点。否则,我总是需要双倍的线程数来重叠设备/主机任务。@MaJac89-是的,您的问题是关于卸载的,但您使用OpenMP来完成,并且任务pragma将在并行区域之外被忽略;卸载不会改变这一点。特别是对于卸载,执行target子句的是“遭遇任务”;需要有一个线程绑定到目标构造。谢谢,我将重试(我已经尝试将所有内容都包含在一个并行区域中,结果如下:对于1个线程,行为与我发布的串行执行相同,每个线程有2个线程执行一个任务,但执行卸载部分的线程会等待设备完成其工作,这是我无法理解的)。但是,我将尽快编辑代码,以便更好地解释我的观点。@MaJac89 OpenMP 4.0说“遇到目标构造的任务将在构造结束时等待,直到区域执行完成。”看起来您需要OpenMP 4.1和
omp target nowait
子句。@IlyaVerbin是的,我理解,但在OpenMP 4.0规范的后面,当他们写任务调度时,您可以读到:“任务调度点隐含在以下位置:[…]目标区域生成之后的点”。因此,我希望遇到目标区域的线程暂停当前任务的执行,并切换到另一个任务的执行(如果另一个独立任务可用)。此外,请查看这些引用并查找“async”。
#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