我有一个用例,其中x86 CPU必须将64字节数据写入PCIe从设备,其内存已被mmapp'ed到用户空间。截至目前,我使用memcpy来做到这一点,但事实证明它非常慢。我们可以使用像_mm_stream_si128这样的英特尔SSE内在函数来加速它吗?或者除了使用DMA之外的任何其他机制。
目标是将所有64个字节打包到一个TLP中并在PCI总线上发送以减少开销。
答案 0 :(得分:1)
据我了解,内存映射I / O并不能使某些存储指令变得特殊。来自movq mem, xmm
的8B商店与来自mov mem, r64
的商店相同。
我认为如果你有64B写入MMIO,你应该用它生成的最有效的指令来做,然后刷新缓存行。生成64B缓冲区,然后执行memcpy
(或者使用四个movdqa
或两个AVX vmovdqa
自行完成)是浪费时间,除非您希望生成64B的代码比memcpy更慢,更容易被中断。定时器中断可以随时进入,包括在你的memcpy期间,如果你在用户空间,你无法禁用中断。由于您无法保证完整的64B写入,因此完全缓存行写入的概率为99.99%,而概率为99.99999%。不会有所作为。
Streaming stores可能会避免CPU在上一次写入的clflush
之后执行读取所有权。 clwb
isn't available yet, so the only option is clflush
, which evicts the data from cache
非临时加载/存储是所谓的弱排序。 IDK,如果这意味着你需要更多的围栏来保证订购。
流式加载/存储的一个用例是copying from uncacheable memory, like video RAM。我不确定将它们用于MMIO。我找到this article about it,谈论如何从MMIO读取而不只是获得相同的缓存值。