在this示例程序我发现了这个注释:
/* Hardware delivers at most ef_vi_receive_buffer_len() bytes to each
* buffer (default 1792), and for best performance buffers should be
* aligned on a 64-byte boundary. Also, RX DMA will not cross a 4K
* boundary. The I/O address space may be discontiguous at 4K boundaries.
* So easiest thing to do is to make buffers always be 2K in size.
*/
#define PKT_BUF_SIZE 2048
我很感兴趣为什么为了获得最佳性能缓冲区应该在 64 字节边界上对齐
?例如,为什么 2000 个缓冲区比 2048 个缓冲区慢?我想这就是 64 位计算机的工作方式 - 由于某种原因,memcpy 2048 字节比 2000 字节更快?
为什么恰好 2048 个缓冲区更快,也许您可以链接“最小示例”,其中“更大但 64 字节对齐”的缓冲区更快?
最佳答案
64 字节是当代架构中缓存行 的流行大小。任何从内存中获取的内容都会获取整个缓存行。通过将数据与缓存行边界对齐,您可以最大限度地减少读取数据时需要获取的缓存行数以及写入数据时变脏的缓存行数。
当然,数据的大小也很重要。例如,如果数据的大小除以缓存行的大小,则仅按大小对齐就完全没问题。
相比之下,假设您的数据有 96 个字节。如果按 32 字节对齐,则最多可以使用三个缓存行:
|............DDDD|DDDDDDDDDDDDDDDD|DDDD............|
相比之下,如果你对齐 64 字节(需要另外 32 字节的填充),你只需要两个缓存行:
|................|DDDDDDDDDDDDDDDD|DDDDDDDDPPPPPPPP|
(D
= data,P
= padding,每个字符代表4个字节。)
当您同时修改内存时,缓存行甚至更值得关注。每次弄脏一个缓存行时,所有其他已获取同一缓存行的 CPU 可能不得不丢弃并重新获取这些缓存行。不小心将不相关的共享数据放在同一缓存行上称为“错误共享”,插入填充通常用于避免这种情况。
关于c++ - 为什么缓冲区应该在 64 字节边界上对齐以获得最佳性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34860366/