从 Sandy Bridge 开始,采用服务器非核心设计的英特尔处理器支持默认启用的 Data Direct I/O (DDIO)。使用 DDIO,针对 WB 类型的系统内存位置的入站 PCIe 写入是分配写入事务。
对于完整写入(写入整个高速缓存行),IIO 首先通过使一致性域中的所有副本无效来获得目标高速缓存行的所有权,但在与原始设备连接的同一 NUMA 节点中存在的 L3 中除外. 如果目标 L3 中不存在该行,则分配一个 L3 条目,这可能需要驱逐另一行以腾出空间。写入在 L3 中执行,线路的一致性状态变为 M。这意味着数据不会发送到其地址映射到的内存控制器。部分写入在 IIO(位于一致性域中)中缓冲,直到最终被逐出以写入 LLC(分配或更新)。在 DDIO 中,读取永远不会分配。
即使禁用了 DDIO,也可以在 DDIO 中缓冲 PCIe 写入。当cudaMemcpyAsync
甚至cudaMemcpy
返回时,无法保证所有写入都已到达英特尔处理器上的持久性域(除非您拥有整个系统持久性)。此外,内存副本不能保证是持久原子的,也不能保证字节从 IIO 移动到目标内存控制器的顺序。您需要一个标志来告诉您是否保留了整个数据。
您可以使用屏障(cudaStreamSynchronize()
或cudaDeviceSynchronize()
)在主机上等待,直到数据复制操作完成,然后刷新每个缓存行,然后按该顺序写入标志。