减少内存和CPU使用量

  • 本文关键字:CPU 使用量 内存 c
  • 更新时间 :
  • 英文 :


在一个CPU功率和内存有限的系统中,我想知道是否可以使用这个技巧(不起作用(来获得一些性能。目标是减少内存和CPU的使用。

假设我在运行时的某个时刻分配了6*sizeof(int),以后不再需要指针的第一个值。在这一点上,我将拥有分配的内存的一部分,更具体地说是程序不需要也不能使用的1*sizeof(int)

因此,我的第一个想法是在另一个指针中分配5*sizeof(int),移动数据并释放第一个指针,但这样做,我将不得不在短时间内使用更多内存(2个指针(,并且通过将数据从地址移动到其他地址,我将失去CPU性能。

我的第二个想法在理论上更好,但它没有起作用,我可以直接将第二个指针分配到第一个指针的第二地址,而不是移动数据,通过这样做,我不必使用CPU来移动数据,我的新指针工作得很好,直到我释放旧指针。。。基本上这就是我尝试过的代码:

void Print(int* k, int size)
{
for(int i=0;i<size;i++)
{
printf("%d, ",k[i]);
}
}
void Scan(int* k, int size)
{
for(int i=0;i<size;i++)
{
k[i] = i+1;
}
}
int main() {
int* a = malloc(6 * sizeof(int));
Scan(a,6);
Print(a, 6);
int* p = malloc(5 * sizeof(int));
p = a+1;
free(a);
Print(p, 5);

return 0;
}

有办法让它工作吗?

这不起作用——您必须在malloc()之前返回的确切指针上调用free(),而对free()的调用将始终释放malloc()调用之前分配的全部内存。malloc()free()不支持部分释放。

如果你想更改现有堆分配的大小,你可以通过对其调用realloc((来尝试。请注意,realloc()很难正确使用(例如,它返回一个新的指针值,而不是旧的指针值(。例如,如果您想从6-int堆分配前面删除第一个int,您需要将后面的5个ints中的每一个复制到它之前的int上,然后执行a = realloc(a, 5*sizeof(int))。这样做是否真的能为你节省可观的RAM或CPU使用量,这是一个悬而未决的问题(就我个人而言,我对此表示怀疑,除非你想删除的实际上是几千个或更多的ints,而不仅仅是一个(。

也许你最好的选择是放弃花哨的单独堆分配,只使用指针数学来完成任务:

int main() {
int* a = malloc(6 * sizeof(int));
Scan(a,6);
Print(a, 6);
Print(a+1, 5);
free(a);
return 0;
}

对于给定的示例代码,您也不需要第一个堆分配,因此您可以使用堆栈数组来降低程序的复杂性和内存使用率:

int main() {
int a[6];
Scan(a,6);
Print(a, 6);
Print(a+1, 5);
return 0;
}

TL;DR:不,没有办法让它工作(使用系统的分配器(。


free()既不知道也不想知道指向或进入分配块的指针,只知道它接收的副本(按值(作为其参数。并且它仅根据先前由malloc()calloc()分配的整个块来工作。因此,在不完全释放已分配块的情况下,不能使用free来减小该块的大小。

可以使用realloc()缩小内存分配,但

  1. 内存从分配的高地址端释放,与您想要的相反。您需要将要保留的数据转移到数组的开头。

  2. 即使在减小尺寸(而不是增大尺寸(时,更改也不一定要执行到位。这意味着realloc可能比您描述的第一种策略更糟糕。您最终可能会临时使用相同的额外内存和相同的复制成本,加上偏移数组内容的成本,如(1(所述。

  3. 无论如何,释放六个int大小的区域中的int大小的部分可能没有什么用处,因为分配器通常不会以足够精细的粒度进行操作,从而产生影响。您可以减少正式的分配大小,但在实践中,这可能不会为程序分配任何额外的空间。

将此代码分解为

int main() {
int* a = malloc(6 * sizeof(int)); // allocate 6 ints
Scan(a,6);
Print(a, 6);
int* p = malloc(5 * sizeof(int)); // allocate 5 ints
p = a+1; // overwrite the pointer to those 5 ints ==> leak
free(a); // release the memory the p points at
Print(p, 5); // undeifined behavior

return 0;
}

这将适用于

int main() {
int* a = malloc(6 * sizeof(int));
Scan(a,6);
Print(a, 6);
int* p = a + 1; // new pointer to malloced memory that skips the first entry
Print(p, 5);

return 0;
}

最新更新