我观察到一种奇怪的行为,想知道它是否与英特尔至强融核相关。

我有一些示例代码,基本上是每个人都知道的矩阵乘法(三个嵌套的 for 循环)。我使用 OpenMP 4.0 将计算卸载到英特尔 MIC target pragma 并将三个矩阵映射为 map(to:A,B) map(tofrom:C).

现在,我观察到的是对于小矩阵,例如1024x1024 内存传输花费了非常长的时间。与本机版本(相同的代码、相同的并行化策略,只是没有卸载)相比,卸载版本多消耗约 320 毫秒的时间。我对代码进行了热身运行以消除初始化开销。

与 Nvidia Tesla K20 相比,在没有注意到的情况下复制相同数量的内存,这 320 毫秒非常糟糕。

是否有一些环境设置可以提高内存传输速度?

另外一个问题:我通过 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 一起使用?如果是,怎么办?

有帮助吗?

解决方案

可能是 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))

其他提示

既然您说“我对代码进行了预热运行以消除初始化开销”,我假设您通过卸载虚拟部分来启动卸载运行时。我记得有一个调整可以启动它“on_offload”(默认)或在程序初始化时(OFFLOAD_INIT=on_start)。不管怎样,DMA引擎中也有一条快速路径。当(要传输的)缓冲区与页面大小对齐时,将采用快速路径。对于卸载应用程序,您可以简单地设置一个环境变量以及一个阈值整数B|K|M|G|T,其中M 是兆字节(例如,MIC_USE_2MB_BUFFERS=2M)。该阈值定义了使用大页面之前所需的缓冲区大小。所以你得到两件事:大页面和更快的传输!即使协处理器上引入了透明大页 (THP),此功能仍然有意义。

在简单尝试 OFFLOAD_INIT=on_start 和 MIC_USE_2MB_BUFFERS=0 后,您可能需要对齐缓冲区 主持人 相应的侧面(最大)的。矢量宽度和页面大小;-)。请记住,没有额外的卸载条款(LEO;但不确定 OpenMP 4.0)主机缓冲区的对齐方式很简单 遗传 通过卸载部分。对齐到 2MB 应该涵盖所有内容(但是您可以使分配更加智能,以避免为小缓冲区浪费资源)。这样,如果需要,您应该有足够的关键字来查找更多背景。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top