【问题标题】:How do I ensure buffer memory is aligned?如何确保缓冲内存对齐?
【发布时间】:2010-12-11 14:05:38
【问题描述】:

我正在使用硬件接口发送数据,这需要我设置一个DMA 缓冲区,该缓冲区需要在 64 位边界上对齐。

DMA 引擎要求缓冲区在至少 32 位边界(4 字节)上对齐。为最佳 性能缓冲区应在 64 位边界(8 字节)上对齐。传输大小必须是 4 字节的倍数。

我使用posix_memalign 来创建这样的缓冲区...

posix_memalign ((void**)&pPattern, 0x1000, DmaBufferSizeinInt32s * sizeof(int) ) )

pPattern 是一个指向 int 的指针,是我的缓冲区的开始,它是 DmaBufferSizeinInt32s deep。

我的缓冲区是否在 64 位上对齐?

【问题讨论】:

    标签: c++ memory alignment dma


    【解决方案1】:

    我不了解您的硬件,也不知道您是如何获得 pPattern 指针的,但这似乎很冒险。我熟悉的大多数 DMA 都需要物理连续 RAM。操作系统只为用户程序提供几乎连续的 RAM。这意味着 1 MB 的内存分配可能由多达 256 个未连接的 4K RAM 页组成。

    大部分时间内存分配将由连续的物理部分组成,这可能导致大部分时间但并非总是如此。您需要一个内核设备驱动程序来提供安全的 DMA。

    我对此感到疑惑,因为如果您的 pPattern 指针来自设备驱动程序,那么您为什么需要更多地对齐它?

    【讨论】:

      【解决方案2】:

      是的,您的缓冲区在 64 位上对齐。它也在 4 KB 边界上对齐(因此为 0x1000)。如果您不想要 4 KB 对齐,请传递 0x8 而不是 0x1000 ...

      编辑:我还要注意,通常在编写 DMA 链时,您是通过未缓存的内存或某种非基于缓存的写入队列来写入它们的。如果是这种情况,您还希望将 DMA 链与缓存行大小对齐,以防止缓存回写覆盖 DMA 链的开头或结尾。

      【讨论】:

      • 不确定是否需要 4KByte 边界对齐...应该吗?
      • 我基本上写的是 10 x 32 位字的数据对象。我想每次发送 10 x 32 位字的整数。我目前在每次 DMA 传输中对 400 x 320 位数据对象进行 DMA。我不确定缓冲区的大小(400 x 10 x 32 位)与对齐方式有什么关系,如果有的话。我应该调整缓冲区的大小吗?
      • 我无法回答这个问题。一方面,我不知道您的平台是什么。在 windows 下,内存页面以 4K 页面分配。这意味着您一次只能将整个页面设置为未缓存,因此您可能需要 4K 对齐。唉,不过,如果不了解更多关于您的系统的信息,我不能肯定地说...
      • 系统是 RedHat Enterprise Linux 内核 2.6.18.8。在单板计算机上嵌入运行。
      • 在 x86 上运行?如果是这样,我猜 linux 在 TLB 中也使用 4K 页面,因此 4K 对齐将确保您绝对不在缓存中并且不会影响应该缓存的内容。
      【解决方案3】:

      正如 Goz 指出的那样,但 (imo) 不太清楚:您要求按 0x1000 字节(第二个参数)对齐,这远远超过 64 位。

      您可以将调用更改为:

      posix_memalign ((void**)&pPattern, 8, DmaBufferSizeinInt32s * sizeof(int)))
      

      这可能会使调用更便宜(更少浪费的内存),并且在任何情况下都更清晰,因为您要求的内容与您实际想要的内容更接近。

      【讨论】:

      • 好的,我想我现在明白了……posix_memalign 的中间参数是对齐。虽然我的值是 64 位的一个因子,但它实际上设置为 4096 字节。
      猜你喜欢
      • 2018-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多