将 Intel 的 #pragma offload 转换为 Xeon Phi 的 OpenMP(性能问题和其他问题)

Translating Intel's #pragma offload to OpenMP for Xeon Phi (performance issues and other questions)

我使用 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 是为了更好地了解 运行 期间发生的事情。

这是我的 problems/questions:

还有一些其他的问题:

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

On the testing machine I have two Intel Phi cards. Since I want to use the 2nd one I do this: #pragma omp target device(1).... Is that correct?

据我所知,device(0) 表示默认卡,device(1) 表示第一张卡,device(2) 表示第二张卡。

If I do #pragma omp target device(5)... the code still works! And it runs on one of the Phi cards (and not the CPU) because the performance is similar. Why is that?

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

I also tried my software (the OpenMP version) on a machine without an Xeon Phi and it run just fine on the CPU! Is this guaranteed? When you have no accelerator on the machine the target device(1) is ignored?

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

Is it possible to do something like std::cout << print_phi_card_name_or_uid(); inside an OpenMP offloaded region (so I will know for sure in which card my software is running)?

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