c++ - 为什么缓冲区应该在 64 字节边界上对齐以获得最佳性能?

标签 c++ memory-management latency

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/

相关文章:

node.js - 水平扩展在服务器之间共享输入的应用程序

c++ - 如何使用 VS2015 获取语言环境名称?

c++ - 将对象添加到预先分配的对象数组

c++ - 范围限制资源管理 (SBRM) 是什么意思?

c++ - 如果使用 delete 而不是 free 删除使用 malloc 分配的内存怎么办

ios - 此时不拥有的引用计数的不正确减少

c++ - 为什么当新数组、调整 vector 大小和push_back到 vector 时会出现bad_alloc?

python - 如何在 tensorflow 中使用自定义 python 函数预取数据

networking - 如何将网络请求分派(dispatch)到(地理上)最近的服务器

C++ sdl : can i have an sdl-opengl window inside a menu and buttons i created with glade?