我使用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卸载仅是Intel编译器的一部分(我认为)。因此,我想将其转换为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
它来更好地了解运行时发生的情况。
这是我的问题/疑问:
#pragma offload
)一样快。这里没什么奇怪的。MIC_TIME
两者的相同,但是CPU_TIME
不同(OpenMP版本更高)。这是为什么?以下是一些其他问题:
#pragma omp target device(1)...
。那是对的吗?#pragma omp target device(5)...
,代码仍然有效!而且它运行在Phi卡之一(而不是CPU)上,因为性能相似。这是为什么?target device(1)
被忽略吗?std::cout << print_phi_card_name_or_uid();
在OpenMP卸载区域内执行类似的操作(这样我就可以确定我的软件在哪个卡上运行)?第二个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,device(0)表示默认卡,device(1)表示第一张卡,device(2)是第二张卡。
如果我执行#pragma omp target device(5)...代码仍然有效!而且它运行在Phi卡之一(而不是CPU)上,因为性能相似。这是为什么?
因为liboffload执行此(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()
区分主机和加速器的功能。也许有一些特定于Intel的界面可以做到这一点。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句