中型内存分配的最佳大小是多少?
对于序列化系统,我需要分配缓冲区来写入数据。所需的大小事先未知,因此基本模式是 malloc
N
字节,如果需要更多字节,则使用 realloc
。 N
的大小足以容纳大多数对象,因此很少会进行重新分配。
这让我认为可能存在一个最佳的初始字节数,malloc
比其他字节更容易满足。我猜测接近 pagesize
的地方,尽管不一定完全是 malloc
需要一些空间进行内务处理。
现在,我确信这是一个无用的优化,如果它真的很重要,我可以使用一个池,但我很好奇;我不可能是第一个认为给我最容易分配的字节块作为开始的程序员。有没有办法确定这一点?
任何专门适用于现代 GCC/G++ 和/或 Linux 的答案都将被接受。
For a serializing system, I need to allocate buffers to write data into. The size needed is not known in advance, so the basic pattern is to malloc
N
bytes and use realloc
if more is needed. The size of N
would be large enough to accommodate most objects, making reallocation rare.
This made me think that there is probably an optimal initial amount of bytes that malloc
can satisfy more easily than others. I'm guessing somewhere close to pagesize
, although not necessarily exactly if malloc
needs some room for housekeeping.
Now, I'm sure it is a useless optimization, and if it really mattered, I could use a pool, but I'm curious; I can't be the first programmer to think give me whatever chunk of bytes is easiest to allocate as a start. Is there a way to determine this?
Any answer for this that specifically applies to modern GCC/G++ and/or linux will be accepted.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
从阅读 this wiki 页面看来,您的答案会根据 malloc 的实现而有很大差异您正在使用的操作系统。阅读有关 OpenBSD 的 malloc 的内容特别有趣。听起来您也想查看 mmap,但猜测我会说分配默认页面大小(4096?)将对其进行优化。
From reading this wiki page it seems that your answer would vary wildly depending on the implementation of malloc you're using and the OS. Reading the bit on OpenBSD's malloc is particularly interesting. It sounds like you want to look at mmap, too, but at a guess I'd say allocating the default pagesize (4096?) would be optimised for.
我对您的建议是找到一个合适的 malloc/realloc/free 源代码,这样您就可以在同一源模块(并使用相同的内存结构)中与其他模块一起实现自己的“malloc_first”,该模块只需分配并返回第一个可用块大于或等于传递的minimum_bytes参数。如果传递 0,您将获得第一个块周期。
适当的声明可以是“
我不知道这样的承诺如何可行”。我建议您使用 Linux 来尝试,因为所有源代码都可用。
My suggestion to you would be to find an appropriate malloc/realloc/free source code such that you can implement your own "malloc_first" alongside the others in the same source module (and using the same memory structures) which simply allocates and returns the first available block greater than or equal to a passed minimum_bytes parameter. If 0 is passed you'll get the first block period.
An appropriate declaration could be
How doable such an undertaking would be I don't know. I suggest you attempt it using Linux where all source codes are available.
在类似情况下完成的方式是第一个 malloc 分配一些重要但不是太大的块,这适合大多数情况(如您所描述的),以及每个后续的 realloc > 调用将请求的大小加倍。
因此,如果一开始您分配 100 个,下次您将
realloc
200,然后是 400、800,依此类推。这样每次执行后,后续重新分配的机会就会降低。如果我没记错的话,这就是 std::vector 的行为方式。
编辑后
最佳初始分配大小将是一侧能够覆盖大部分情况,但另一侧不会太浪费的大小。如果您的平均情况是 50,但可能会飙升至 500,则您需要最初分配 50,然后在每个下一个
realloc
中分配两倍或三倍(或乘以 10),以便达到 500在 1-3 个realloc
时间内,但任何进一步的realloc
都不太可能且很少发生。所以这基本上取决于您的使用模式。The way it's done in similar cases is for the first
malloc
to allocate some significant but not too large chunk, which would suit most cases (as you described), and every subsequentrealloc
call to double the requested size.So, if at first you allocate 100, next time you'll
realloc
200, then 400, 800 and so on. In this way the chances of subsequent reallocation will be lower after each time you do it.If memory serves me right, that's how
std::vector
behaves.after edit
The optimal initial allocation size would be the one that will cover most of your cases on one side, but won't be too wasteful on the other side. If your average case is 50, but can spike to 500, you'll want to allocate initially 50, and then double or triple (or multiple by 10) every next
realloc
so that you could get to 500 in 1-3realloc
s, but any furtherrealloc
s would be unlikely and infrequent. So it depends on your usage patterns, basically.