我使用英特尔 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 版本与 Intel 版本一样快 (
#pragma offload
)。这里没有什么奇怪的。 - 第二个代码块的 OpenMP 版本比 Intel 版本慢 5 倍。但是,
MIC_TIME
两者相同,但CPU_TIME
不同(OpenMP 版本要高得多)。这是为什么? - 我的英特尔指令是最优的吗?
- 我的 Intel -> 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();
(因此我可以确定我的软件在哪张卡上运行)?