我正在观察一个奇怪的行为,并想知道它是否与英特尔至强有关。
我有一个小例子代码基本上是每个人都知道的矩阵乘法(三个嵌套for循环)。我将计算卸载到具有OpenMP 4.0 target
编译指示的Intel MIC,并使用map(to:A,B)
map(tofrom:C)
映射三个矩阵。
现在,我观察到的是对于小矩阵,例如1024x1024内存传输耗时极长。与本机版本(相同的代码,相同的并行化策略,只是没有卸载)相比,卸载版本消耗大约320ms的时间。我做了一个热身运行的代码来删除初始化开销。
与Nvidia Tesla K20相比,复制相同数量的内存而没有注意到这个320ms是非常糟糕的。
是否有一些环境设置可以提高内存传输速度?
另外一个问题: 我通过OFFLOAD_REPORT环境变量启用了卸载报告。报告中显示的两个时间结果有何不同之处:
[Offload] [HOST] [Tag 5] [CPU Time] 26.995279(seconds)
[Offload] [MIC 0] [Tag 5] [CPU->MIC Data] 3221225480 (bytes)
[Offload] [MIC 0] [Tag 5] [MIC Time] 16.859548(seconds)
[Offload] [MIC 0] [Tag 5] [MIC->CPU Data] 1073741824 (bytes)
MIC时间丢失10秒(内存传输?)
第三个问题。是否可以在英特尔MIC中使用固定内存?如果是,怎么样?
答案 0 :(得分:1)
既然你说“我做了一个代码的预热运行以消除初始化开销”,我假设您通过卸载虚拟部分来启动卸载运行时。我记得有一个调整来启动它“on_offload”(默认)或程序初始化时(OFFLOAD_INIT = on_start)。无论如何,DMA引擎中还有一个快速路径。当缓冲区(要传输)与页面大小对齐时,采用快速路径。对于卸载应用程序,您可以简单地设置环境变量以及阈值integerB | K | M | G | T,其中M是兆字节(例如,MIC_USE_2MB_BUFFERS = 2M)。此阈值定义在使用大页面之前所需的缓冲区大小。所以你得到两件事:巨大的页面和更快的转移!即使在协处理器上引入透明大页面(THP),此功能仍然有意义。
在尝试OFFLOAD_INIT = on_start和MIC_USE_2MB_BUFFERS = 0之后,您可能需要相应地对齐主机侧的缓冲区(最大值为.vector-width和page-size ;-)。请记住,没有额外的卸载子句(LEO;但不确定OpenMP 4.0)主机缓冲区的对齐只是由卸载部分继承。对齐2MB应该涵盖所有内容(但是你可以使你的分配更加智能,以避免浪费资源用于小缓冲区)。有了它,您应该有足够的关键字,以便在需要时找到更多背景信息。
答案 1 :(得分:1)
MIC上的内存分配可能需要时间。尝试并分离三个开销来源,以便更好地了解时间的变化:
// Device initialization
#pragma offload_transfer target(mic)
...
// Memory allocation and first data transfer
// This is expected to have overhead proportional to the amount of memory allocated
// Doing at least one transfer will speed up subsequent transfers
#pragma offload_transfer target(mic) in(p[0:SIZE] : alloc_if(1) free_if(0))
...
// This transfer should be faster
// For large sizes, approaching 6 GiB/s
#pragma offload_transfer target(mic) in(p[0:SIZE] : alloc_if(0) free_if(0))