【发布时间】:2020-08-22 03:43:25
【问题描述】:
我正在尝试根据此处的要求实现自定义分配器以使用标准容器: https://en.cppreference.com/w/cpp/named_req/Allocator
我目前正在尝试实现一个线性分配器,但我在内存对齐方面遇到了困难。
分配一块内存后,我想知道块中每个对象之间需要多少填充以优化 cpu 读/写。
我不确定地址对齐是否应该是整除的
- 按 cpu 字长(32 位机器上为 4 字节,64 位机器上为 8 字节)
-
sizeof(T) -
alignof(T)
我在不同的地方读到不同的答案。
例如在this 问题中,接受的答案是:
通常的经验法则(直接来自 Intel 和 AMD 的优化) 手册)是每个数据类型都应该按自己的大小对齐。一个 int32 应该在 32 位边界上对齐,一个 int64 在 64 位上 边界,等等。 char 适合任何地方。
因此,根据该答案,地址对齐应该可以被sizeof(T)整除。
关于this 问题的第二个答案表明:
CPU 总是以其字长(在 32 位处理器上为 4 字节)读取, 因此,当您执行未对齐的地址访问时 - 在处理器上 支持它——处理器将读取多个单词。
所以根据这个答案,地址对齐应该可以被 cpu 字长整除。
所以我看到一些关于如何优化 cpu 读/写数据对齐的相互矛盾的陈述,我不确定我是否理解不正确或者有一些错误的答案?也许有人可以帮我弄清楚地址对齐应该被什么整除。
【问题讨论】:
-
这取决于您打算将 RAM 用于什么目的,如果您要分配大块,则页面对齐可能会更好。没有一种适合所有解决方案的解决方案,这就是编译器在编译时根据类型填充结构的原因,除非另有说明。如果您想同时使用 32 位和 64 位实例,只需以浪费一些 RAM 为代价对齐到 64 位。
-
@Geoffrey 所以根据你的回答,我可以假设我应该根据 cpu 字大小而不是
sizeof(T)对齐数据? -
sizeof(T)可能是 3 个字节,这取决于类型,所以是的,对齐 CPU 字长。同样,如果您要处理大块数据的副本,则与页面大小对齐会更好。 -
@Geoffrey 不仅仅是普通的对象数据。对齐也是我传递给分配器的参数,所以我可以用这种方式实例化它:
m_Alignment = sizeof(T*)不能吗?如果我对齐 4 个字节或 8 个字节(取决于 cpu 字大小),如果第一个地址可被 4/8 整除,是否总是有 0 填充?如果是这样,如果我可以保证起始地址可以被 4/8 整除,这难道不是一种优化,可以确保池中有更多对象吗?如果是这样的话,我可以用 malloc 保证这样的地址划分?
标签: c++ c++11 memory-management cpu allocator