如何确保缓冲区内存对齐?

发布于 2024-08-09 08:24:32 字数 502 浏览 7 评论 0原文

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

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

我使用 posix_memalign 创建缓冲区,如下面的代码片段所示。

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

pPattern 是一个指向 int 的指针,并且是深度为 DmaBufferSizeinInt32s 的缓冲区的开始。

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

I am using a hardware interface to send data that requires me to set up a DMA buffer, which needs to be aligned on 64 bits boundaries.

The DMA engine expects buffers to be aligned on at least 32 bits boundaries (4 bytes). For optimal performance the buffer should be aligned on 64 bits boundaries (8 bytes). The transfer size must be a multiple of 4 bytes.

I create buffers using posix_memalign, as demonstrated in the snippet bellow.

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

pPattern is a pointer to an int, and is the start of my buffer which is DmaBufferSizeinInt32s deep.

Is my buffer aligned on 64bits?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

焚却相思 2024-08-16 08:24:32

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

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

Yes, your buffer IS aligned on 64-bits. It's ALSO aligned on a 4 KByte boundary (hence the 0x1000). If you don't want the 4 KB alignement then pass 0x8 instead of 0x1000 ...

Edit: I would also note that usually when writing DMA chains you are writing them through uncached memory or through some kind of non-cache based write queue. If this is the case you want to align your DMA chains to the cache line size as well to prevent a cache write-back overwriting the start or end of your DMA chain.

黯然#的苍凉 2024-08-16 08:24:32

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

您可以将调用更改为:

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

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

As Goz pointed out, but (imo) a bit less clearly: you're asking for alignment by 0x1000 bytes (the second argument), which is much more than 64 bits.

You could change the call to just:

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

This might make the call cheaper (less wasted memory), and in any case is clearer, since you ask for something that more closely matches what you actually want.

舞袖。长 2024-08-16 08:24:32

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

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

我想知道这一点,因为如果你的 pPattern 指针来自来自设备驱动程序,那么为什么你需要更多地对齐它?

I don't know your hardware and I don't know how you are getting your pPattern pointer, but this seems risky all around. Most DMA I am familiar with requires physical continuous RAM. The operating system only provides virtually continuous RAM to user programs. That means that a memory allocation of 1 MB might be composed of up to 256 unconnected 4K RAM pages.

Much of the time memory allocations will be made of continuous physical pieces which can lead to things working most of the time but not always. You need a kernel device driver to provide safe DMA.

I wonder about this because if your pPattern pointer is coming from a device driver, then why do you need to align it more?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文