从 x86 CPU 生成 64 字节读取 PCIe TLP

hag*_*i_e 4 x86 pci-e

将数据写入 PCIe 设备时,可以使用写入组合映射来提示 CPU 应该向设备生成 64 字节的 TLP。

是否可以为读取做类似的事情?以某种方式提示 CPU 读取整个缓存行或更大的缓冲区,而不是一次读取一个字?

Pet*_*des 6

英特尔有一份关于从视频 RAM 复制到主内存的白皮书;这应该是相似的,但要简单得多(因为数据适合 2 或 4 个向量寄存器)。

它说 NT 加载会将整个缓存行数据从 WC 内存拉入 LFB:

普通加载指令以指令请求的相同大小为单位从 USWC 内存中提取数据。相比之下,像 MOVNTDQA 这样的流式加载指令通常会将完整的缓存数据行拉到 CPU 中的特殊“填充缓冲区”。随后的流式加载将从该填充缓冲区中读取,从而产生更少的延迟。

使用 AVX2_mm256_stream_load_si256()或 SSE4.1/AVX1 128 位版本。

填充缓冲区是一种有限的资源,因此您肯定希望编译器生成 asm 来执行 64 字节缓存行的两个对齐加载,然后存储到常规内存中。

如果您一次处理多个 64 字节块,请参阅英特尔的白皮书,了解有关使用在 L1d 中保持热态的小型反弹缓冲区的建议,以避免将存储与 NT 负载混合到 DRAM 中。(到 DRAM 的 L1d 驱逐,如 NT 存储,也需要行填充缓冲区,LFB)。


请注意,_mm256_stream_load_si256()是没有用在所有的比WC其他存储器类型。NT 提示在当前硬件上被忽略,但无论如何与常规负载相比,它会花费额外的 ALU uop。有prefetchnta,但那是一种完全不同的野兽。