数组内存分配和使用
这是来自记忆,所以我可能会滥用几句话,但意义应该是可以理解的
我现在在大学,在编程方面做了一个BIT专业 - 我们开始使用C ++,当我们开始使用数组时,我们的C ++老师(一个有着奇怪想法和编程规则的老师,比如没有任何评论允许)告诉我们,我们应该使我们的数组大小为4的倍数更高效:
char exampleArrayChar[ 4 ]; //Allowed
float exampleArrayChar[ 6 ]; //NOT Allowed
int exampleArrayChar[ 8 ]; //Allowed
他说这背后的原因是因为计算机进行内存分配的方式。
计算机为每个数组元素分配了四个字节的内存地址/位置 - 所以在两个内存组中完成了一个8元素数组。
所以问题是,如果你创建了一个大小为6的数组,它将分配2个4组,然后将这些字节中的2个(8个中的)标记为无效/无效,使它们不可用,直到整个数组从记忆。
虽然这对我来说似乎对其他计算机数学(如1GB = 1024MB,而不是正好是1000)而言似乎合理,但我有兴趣知道:
环顾网络,我一直无法找到任何主要用途或相关性。
float exampleArrayChar[ 6 ]; //NOT Allowed
考虑到float
是4字节(几乎普遍,由于广泛采用IEEE-754编码浮点数),任何数量的浮点数已经是四个字节的倍数。 你的例子是24,并没有问题。 在x86(和x64)上,SSE指令确实希望数据是8字节对齐的......再次拥有一个大小为6个元素= 24个字节的float
组不会干扰这一点。
对于对齐而言真正重要的唯一更大的倍数是高速缓存线的大小,其随实现而变化很大(针对x86编译的代码可能发现自己在具有32字节,128字节或其他高速缓存大小的CPU上运行,全部来自同一台机器码)。 是的,高速缓存对齐可以产生巨大的性能差异,但与高速缓存行的对齐不一定更好,事实上,对齐通常会更糟糕,因为它会引起高速缓存映射上的冲突,这类似于虚假共享,就性能而言被关注到。
请参阅什么是“缓存友好”代码? 为什么我的程序在循环8192个元素时很慢? 和其他与这些问题相关的问题。
但是,只要你的教授没有留下任何评论,你应该在院长办公室要求退还你的学费。
假设你的老师真的告诉你你上面说了什么,你的老师会是错的(这根本不会让我感到吃惊)。 然而,真正的事情是,当你从堆中分配内存时,被分配的内存块可能是2的某个倍数的倍数,因为内存最终会以不幸的方式碎片化,否则至少在使用通用内存分配器。 因此,你可能会浪费几个字节。 然而,除非你有许多对象,否则我不打扰这些细节:使用语义正确的方法首先获得程序。
但是,处理这些问题的最佳方法不是首先使用数组,而是使用std::vector<T>
或std::deque<T>
。
那位老师有一些非常时髦(和错误的想法)。 为了解释为什么我们要检查每条语句。
......我们的C ++老师......告诉我们应该让我们的数组大小为4的倍数以提高效率......他说这背后的原因是计算机分配内存空间的方式(空间可能不是正确的工作 - 基本上是阵列中每个元素的内存地址)
C(和C ++)授予如果分配内存(不管类型如何),它将在那里,否则会发生运行时错误。 他可能会说,这是一个很好的做法(不是)分配更多的空间来容纳一些溢出错误。 然而,C和C ++将所有内存授予静态的(我的意思是没有通过new()
动态声明,尽管我不确定这个)array是连续的。 声明某些内容时,只使用您需要使用的内存(资源)数量。
计算机为每个数组元素分配内存地址/位置,每个数组元素为4个 - 所以8个元素的数组在2个内存组中完成(同样,组不是正确的字)
一个int
至少有4个字节,这是唯一一个听到之前引用的意义的句子。 由于您可以通过引用来引用内存中的任何字节,因此除非出现一些环境问题,否则不需要将内存分为四组。
虽然这对我来说在其他计算机数学(例如1GB = 1024MB而不是确切的1000)方面似乎是合理的......
虽然这在其他地方最好讨论,GB和GiB是分开的东西; 在维基百科上查看它。 然而,关于内存,有一个非正式的约定,Byte单元在210,220,230等等上定义了“倍数”。
最后,正如前面的评论者所说,C ++中的正确方法是通过新的容器类,即std::vector<T>
最像数组的容器。 将这种数组声明留给一些非常简单的或者遗留的C代码。