Parallel processing Xeon Phi从主机openMP并行区域异步卸载

Parallel processing Xeon Phi从主机openMP并行区域异步卸载,parallel-processing,openmp,xeon-phi,offloading,Parallel Processing,Openmp,Xeon Phi,Offloading,我在主机openMP代码中使用intel的卸载pragmas。代码如下所示 int s1 = f(a,b,c); #prama offload singnal(s1) in (...) out(x:len) { for (int i = 0; i < len; ++i) { x[i] = ... } } #pragma omp parallel default(shared) { #pragma omp for schedule(d

我在主机openMP代码中使用intel的卸载pragmas。代码如下所示

int s1 = f(a,b,c);

#prama offload singnal(s1) in (...) out(x:len)
{
    for (int i = 0; i < len; ++i)
    {
        x[i] = ...
    }   
}

#pragma omp parallel default(shared)
{
    #pragma omp for schedule(dynamic) nowait
    for (int i = 0; i < count; ++i)
    {
        /* code */
    }

    #pragma omp for schedule(dynamic) 
    for (int j = 0; j < count2; ++j)
    {
        /* code */
    }
}

#pragma offload wait(s1)
{
    /* code */
}
卸载报告指出,上述代码是罪魁祸首。一种临时解决方法是使用常数作为信号,即信号(0),它可以工作。然而,我需要一个更持久的解决方案。任何人都可以了解我的代码中出现了什么问题


谢谢

我不能对第二个代码块发表评论。我对第一个问题有一些看法

第一次卸载总是需要较长的时间,因为它还设置了卸载基础设施。这种结构包括传递环境变量、通过libomp5的mic实现进行复制、设置线程池等

避免这种情况的方法是首先设置一个虚拟卸载,这意味着它实际上不做任何事情,也不是计算块的一部分

在software.intel.com/mic-developer的“培训”选项卡下有一组关于xeon phi协处理器优化的优秀参考资料

另请看software.intel.com/en-us/articles/programming-and-compile-for-intel-many-integrated-core-architecture、software.intel.com/en-us/articles/optimization-and-performance-tuning-for-intel-xeon-phi-coprocessors-part-1-optimization、,和software.intel.com/en-us/articles/optimization-and-performance-tuning-for-intel-xeon-phi-coprocessors-part-1-optimization


很抱歉,URL太长,但stackoverflow不允许我包含两个以上的链接,因为我是新手。

让我补充一下Taylor的回答

第一次卸载确实比后续卸载花费更多的时间,因为初始化工作正在进行。泰勒描绘了那里发生的一些事情。通过使用环境变量offload\u INIT=on\u start,可以避免虚拟卸载。这应该让运行时系统提前完成所有初始化。这样做的开销不会消失,但会从第一次卸载转移到应用程序初始化

您的第二个代码片段的问题似乎是您的卸载针对不同的设备。仅当信号和等待发生在同一目标设备上时,信号和等待才起作用。由于在卸载时没有显式使用
target(mic:0)
子句,因此运行时系统选择不同目标设备的可能性很高

我想提出的一个建议是不要在信令中使用纯整数。通常,该信号表示某个缓冲区已准备就绪。在这些情况下,最好使用缓冲区指针作为信号句柄,因为它对于使用不同缓冲区的并发卸载是唯一的

干杯,
-michael

他们的目标是同一台设备。i、 e.麦克:1。这是为了明确你的反应而做的。整个代码块位于顺序for循环中。因此,在外部for循环的每次迭代中都会调用该函数。初始化在外部for循环之前完成。在我的例子中,这个初始化需要7秒钟(由于malloc数量巨大)。在一轮Malloc之后,每个分配的区域都被“重用”。我忽略了这7秒。这是内-外for循环,每个麦克风卸载需要4毫秒,这是我试图隐藏的。这是
int s1 = f(a,b,c);

#pragma omp parallel default(shared)
{
    #pragma omp single nowait
    {
        #prama offload singnal(s1) in (...) out(x:len)
        {
            for (int i = 0; i < len; ++i)
            {
                x[i] = ...
            }   
        }

    }

    #pragma omp for schedule(dynamic) nowait
    for (int i = 0; i < count; ++i)
    {
        /* code */
    }

    #pragma omp for schedule(dynamic) 
    for (int j = 0; j < count2; ++j)
    {
        /* code */
    }
}

#pragma offload wait(s1)
{
    /* code */
}
device 1 does not have a pending signal for wait(0x1)