我已经理解为什么内存应该根据总线的数据宽度对齐到 4 字节和 8 字节。但是以下陈述使我感到困惑
“IoDrive 要求使用 O_DIRECT 在设备上执行的所有 I/O 必须是 512 字节对齐且大小为 512 字节的倍数。”
将地址对齐到 512 字节需要什么。
我已经理解为什么内存应该根据总线的数据宽度对齐到 4 字节和 8 字节。但是以下陈述使我感到困惑
“IoDrive 要求使用 O_DIRECT 在设备上执行的所有 I/O 必须是 512 字节对齐且大小为 512 字节的倍数。”
将地址对齐到 512 字节需要什么。
将大缓冲区对齐限制归咎于 DMA 的一揽子声明是错误的。
硬件 DMA 传输通常在 4 或 8 字节边界上对齐,因为 PCI 总线一次可以物理传输 32 或 64 位。除了这种基本对齐之外,硬件 DMA 传输还设计为与提供的任何地址一起工作。
但是,硬件处理物理地址,而操作系统处理虚拟内存地址(这是 x86 cpu 中的保护模式结构)。这意味着进程空间中的连续缓冲区在物理内存中可能不连续。除非注意创建物理上连续的缓冲区,否则 DMA 传输需要在 VM 页面边界(通常为 4K,可能为 2M)处分解。
至于需要与磁盘扇区大小对齐的缓冲区,这是完全不正确的;DMA 硬件完全不知道硬盘驱动器上的物理扇区大小。
在 Linux 2.4 O_DIRECT 下需要 4K 对齐,在 2.6 下它已经放宽到 512B。在任何一种情况下,防止单个扇区更新跨越 VM 页面边界并因此需要拆分 DMA 传输可能是一个设计决策。(任意 512B 缓冲区有 1/4 的机会跨越 4K 页面)。
因此,虽然应该归咎于操作系统而不是硬件,但我们可以看到为什么页面对齐的缓冲区更有效。
编辑:当然,如果我们仍然要写入大缓冲区(100KB),那么无论我们是否与 512B 对齐,跨越的 VM 页面边界的数量实际上都是相同的。因此,通过 512B 对齐优化的主要情况是单扇区传输。
如果您不知道自己在做什么,请不要使用 O_DIRECT。
O_DIRECT 表示“直接设备访问”。这意味着它绕过所有操作系统缓存,直接访问磁盘(或可能是 RAID 控制器等)。磁盘访问是基于每个扇区的。
编辑: 对齐要求是 IO 偏移量/大小;这通常不是内存对齐要求。
编辑:如果您正在查看此页面(它似乎是唯一的命中),它还表示内存必须是页面对齐的。