如何在堆栈上对齐缓冲区
How can I align a buffer on the stack?
我正在尝试实现一个按大小对齐的内存缓冲区,这样我就可以使用DMA控制器的模特性来实现环形缓冲区。我知道我可以用memalign来实现这一点,但我想知道是否可以在堆栈上实现,因为到目前为止,我已经能够避免动态内存。我使用的是GCC 4.4.1,我不关心可移植性(嵌入式系统)。
我想做一些类似的事情:
template<uint16_t num_channels, uint16_t buffer_size>
class sampler {
__attribute__((aligned(buffer_size * num_channels * 2)))
uint16_t buffer[buffer_size][num_channels];
};
但GCC当然不会接受非恒定排列(这似乎表明>8的排列可能无论如何都不会得到遵守)。
我想我可以使用C++0x alignas()来实现这一点,但它似乎直到4.8版本才出现在GCC中。
我想一种选择可能是将缓冲区的大小增加一倍,但这似乎浪费了大量空间(我正计划将设备内存的很大一部分用于这个缓冲区)。也许我应该放弃,使用动态记忆。memalign在浪费空间方面会相对高效吗?
有什么想法吗?
您不需要将存储的大小增加一倍,只需要将(alignment - 1)
添加到其中——基本上与memalign
在幕后所做的相同。对于二次方对齐:
char buf[size + (alignment -1)];
char *aligned = (char*)((intptr_t)buf + (alignment - 1) & ~intptr_t(alignment - 1));
我已经很久没有使用链接器命令文件了,但我认为会是这样。
使用创建文件buffer.cpp
char buffer[ BUFFER_SIZE ];
一个对象文件包含名为.bss(用于未初始化的数据)、.data(用于初始化数据)和.text(用于可执行代码)的部分。buffer[]将进入.bss,因为它尚未初始化。
因此,像这样的(gnu)链接器文件应该可以完成
SECTIONS {
.bss 0x0 : {
buffer.o(.bss)
*(.bss)
}
.data : {
*(.data)
}
.text : {
*(.text)
}
}
0x0告诉链接器加载地址为0x0的缓冲区[]。
您能创建一个大于buffer_size
的缓冲区,然后计算其中的偏移量吗?
如果嵌入式系统有内存管理单元,那么就不必担心明智地使用动态内存,尤其是如果每次运行只分配一次。
如果它没有MMU,可以考虑使用链接器映射文件指定一个固定位置。
在具有实际操作系统的系统上,DMA兼容的缓冲区可能无论如何都必须由内核专门分配。
- 如何理解将半精度指针转换为无符号长指针和相关的内存对齐
- 如何创建一个QTableWidgetItem,用长文本右对齐,左边有省略号
- 我可以检测和更改 gcc/g++ 中结构的当前数据对齐设置吗?
- 64位机器上的C++内存对齐
- 为什么我可以将变量存储在不是其最小对齐方式的倍数的地址?
- 使 std::vector 分配对齐内存的现代方法
- 在 capnp FlatArrayMessageReader 的对齐内存缓冲区中接收 zmq 消息
- 如何分配适合容纳 T 类型对象的缓冲区(可能过度对齐、可能有运算符 new 等)
- 不正确的 Vulkan 统一缓冲区内存对齐
- 将缓冲区与 N 字节边界对齐,而不是 2N 字节边界?
- 一个粒子太多:GL_INVALID_VALUE生成错误。<start> 不满足着色器存储缓冲区的最低对齐要求
- 如何在堆栈上对齐缓冲区
- 套接字:在没有memcpy的情况下,使用recvfrom将UDP数据获取到字对齐的缓冲区
- 页面对齐的套接字发送缓冲区
- 为什么缓冲区应该在 64 字节边界上对齐以获得最佳性能
- 对缓冲区使用正确的对齐方式,该缓冲区应该容纳C++中的结构
- Direct3D11缓冲区对齐要求
- OpenGL统一标准缓冲区对齐混淆
- DeviceIoControl缓冲区参数的编组和对齐
- 统一缓冲区对象未对齐.GLSL访问中断