首页 文章

将英特尔的#pragma offload翻译为OpenMP for Xeon Phi(性能问题和其他问题)

提问于
浏览
0

我使用Intel C编译器17.0.01,我有两个代码块 .

第一个代码块在Xeon Phi上分配内存,如下所示:

#pragma offload target(mic:1) nocopy(data[0:size]: alloc_if(1) free_if(0))

第二个块评估上述内存并将其复制回主机:

#pragma offload target(mic:1) out(data[0:size]: alloc_if(0) free_if(0))

这段代码运行得很好,但#pragma offload只是英特尔编译器的一部分(我认为) . 所以,我想将其转换为OpenMP .

这是我将第一个块转换为OpenMP的方法:

#pragma omp target device(1) map(alloc:data[0:size])

这就是我将第二个块转换为OpenMP的方法:

#pragma omp target device(1) map(from:data[0:size])

另外,我使用 export OFFLOAD_REPORT=2 以便更好地了解运行时期间发生的事情 .

这是我的问题/问题:

  • 第一个代码块的OpenMP版本与英特尔版本( #pragma offload )一样快 . 这里没什么奇怪的 .

  • 第二个代码块的OpenMP版本比英特尔版本慢5倍 . 但是,两者的 MIC_TIME 是相同的,但 CPU_TIME 是不同的(OpenMP版本要高得多) . 这是为什么?

  • 我的英特尔指令是否最佳?

  • 我的英特尔 - > OpenMP翻译是否正确且最佳?

这里有一些其他的,有点不同的问题:

  • 在测试机上我有两张Intel Phi卡 . 因为我想使用第二个,所以我这样做: #pragma omp target device(1)... . 那是对的吗?

  • 如果我这样做 #pragma omp target device(5)... 代码仍然有效!它运行在其中一个Phi卡(而不是CPU)上,因为性能相似 . 这是为什么?

  • 我也在没有Xeon Phi的机器上尝试了我的软件(OpenMP版本),它在CPU上运行得很好!这有保证吗?如果机器上没有加速器, target device(1) 会被忽略?

  • 是否可以在OpenMP卸载区域内执行类似 std::cout << print_phi_card_name_or_uid(); 的操作(因此我肯定知道我的软件正在运行哪个卡)?

1 回答

  • 0

    第二个OpenMP代码块再次分配内存 . 您应该将数据映射到设备数据环境,方法是将两个块都包含在 #pragma omp target data map(from:data[0:size]) 中,或者只在第一个块之前添加 #pragma omp target enter data map(alloc:data[0:size]) .

    在测试机器上,我有两张Intel Phi卡 . 由于我想使用第二个,我这样做:#pragma omp target device(1)....这是正确的吗?

    AFAIK,设备(0)表示默认卡,设备(1)表示第一张卡,设备(2)表示第二张卡 .

    如果我做#pragma omp目标设备(5)...代码仍然有效!它运行在其中一个Phi卡(而不是CPU)上,因为性能相似 . 这是为什么?

    因为liboffload does this(liboffload是gcc和icc使用的运行时库) . 但是,OpenMP标准并不保证这种行为 .

    我还在没有Xeon Phi的机器上尝试了我的软件(OpenMP版本),它在CPU上运行得很好!这有保证吗?如果机器上没有加速器,则忽略目标设备(1)?

    是 . 不确定标准,但icc和gcc的卸载是通过这种方式实现的 .

    是否可以执行类似std :: cout << print_phi_card_name_or_uid();在OpenMP卸载区域内(所以我肯定知道我的软件正在运行哪个卡)?

    OpenMP 4.5仅提供 omp_is_initial_device() 功能来区分主机和加速器 . 也许有一些特定于英特尔的界面可以做到这一点 .

相关问题