10

15 年前,在使用 Pascal 编程时,我明白了为什么要使用二的幂进行内存分配。但这似乎仍然是最先进的。

C# 示例:

new StringBuilder(256);
new byte[1024];
int bufferSize = 1 << 12;

我仍然看到这个数千次,我自己使用这个,我仍然在质疑:

我们需要现代编程语言和现代硬件吗?
我想这是很好的做法,但原因是什么?

编辑
例如一个byte[]数组,如答案here所述,2的幂没有意义:数组本身将使用16个字节(?),所以使用240(= 256-16)的大小是否有意义总共适合 256 个字节?

4

5 回答 5

4

我们需要现代编程语言和现代硬件吗?我想这是很好的做法,但原因是什么?

这取决于。这里有两点需要考虑:

  1. 对于小于内存页面大小的大小,2 的幂和分配空间的任意数字之间没有明显差异;
  2. 您主要在 C# 中使用托管数据结构,因此您甚至不知道下面实际分配了多少字节。

假设您正在使用 进行低级分配malloc(),使用页面大小的倍数将被认为是一个好主意,即 4096 或 8192;这是因为它允许更有效的内存管理。

我的建议是只分配你需要的东西,让 C# 为你处理内存管理和分配。

于 2013-08-13T06:21:03.017 回答
2

可悲的是,如果你想在一个 4k 的内存页中保留一块内存是非常愚蠢的......而且人们甚至不知道它:-)(直到 10 分钟前我才知道......我只有预感)......一个例子......这是不安全的代码和实现依赖(使用.NET 4.5 32/64位)

byte[] arr = new byte[4096];

fixed (byte* p = arr)
{
    int size = ((int*)p)[IntPtr.Size == 4 ? -1 : -2];
}

所以 CLR 至少分配了 4096 + (1 or 2) sizeof(int)... 所以它已经超过了一个 4k 内存页。这是合乎逻辑的......它必须将数组的大小保持在某个地方,并将它与数组保持在一起是最聪明的事情(对于那些知道什么是 Pascal 字符串BSTR的人,是的,这是相同的原理)

我要补充一点,.NET 中的所有对象都有一个 syncblck 编号和一个......如果没有的话,RuntimeType它们至少是这样,所以总共有 8 到 16 个字节/对象(这在各个地方都有解释......试试看如果你有兴趣)intIntPtr.net object header

于 2013-08-13T06:47:50.227 回答
1

在某些情况下它仍然有意义,但我更愿意逐个分析我是否需要那种规范,而不是盲目地将其用作良好实践

例如,在某些情况下,您可能希望使用 8 位信息(1 个字节)来寻址表。

在这种情况下,我会让表格的大小为 2^8。

Object table = new Object[256];

这样,您将能够仅使用一个来处理表的任何对象byte

即使表实际上更小并且没有使用所有 256 个位置,您仍然可以保证从表到索引以及从索引到表的双向映射,这可以防止出现错误,例如,如果您有:

Object table = new Object[100];

然后有人(可能是其他人)使用超出表范围的字节值访问它。

也许这种双射行为可能是好的,也许你可以有其他方法来保证你的约束。

可能,鉴于当前编译器的智能程度的提高,它不再是唯一的好习惯了。

于 2013-08-13T06:32:48.457 回答
0

恕我直言,任何以二的算术运算的精确幂结尾的东西都像是一条快车道。2 次方的低级算术运算需要的转数和位操作比任何其他数字需要的 cpu 额外工作更少。

并发现了这个可能的重复项:以 2 的幂次方分配内存更好吗?

于 2013-08-13T06:17:27.143 回答
0

Yes, it's good practice, and it has at least one reason. The modern processors have L1 cache-line size 64 bytes, and if you will use buffer size as 2^n (for example 1024, 4096,..), you will take fully cache-line, without wasted space. In some cases, this will help prevent false sharing problem (http://en.wikipedia.org/wiki/False_sharing).

于 2013-08-13T07:25:16.687 回答