[英]Reduce memory and CPU usage
在我受限于 CPU 功率和 memory 的系统中,我想知道我是否可以使用这个技巧(它不起作用)来获得一些性能。 目标是减少 memory 和 CPU 使用率。
假设我在运行时的某个时刻分配了6*sizeof(int)
,以后不再需要指针的第一个值。 在这一点上,我将分配 memory 的一部分,更具体地说是程序不需要且无法使用的1*sizeof(int)
。
所以我的第一个想法是在另一个指针中分配5*sizeof(int)
,移动数据并释放第一个,但是这样做我将不得不在短时间内使用更多 memory (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()
() 分配的全部 memory 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;
}
...对于给出的示例代码,您也不需要第一个堆分配,因此您可以通过使用堆栈数组来降低程序的复杂性和 memory 的使用:
int main() {
int a[6];
Scan(a,6);
Print(a, 6);
Print(a+1, 5);
return 0;
}
TL;DR:不,没有办法让它工作(使用系统的分配器)。
free()
既不知道也不想要知道指向或指向分配块的指针,除了它接收的副本(按值)作为其第一个参数。 它仅适用于先前由malloc()
或calloc()
分配的整个块。 因此,您不能使用 free 来减少 memory 分配。
您可以使用realloc()
缩小 memory 分配,但是
memory 从分配的高地址端释放,与您想要的相反。 您需要将要保留的数据转移到数组的开头。
即使您减小大小(而不是增加大小),也不一定会就地执行更改。 这意味着使用realloc
可能比使用您描述的第一个策略更糟糕。 您最终可能会临时使用额外的 memory 和相同的复制成本,再加上 (1) 中描述的移动数组内容的成本。
无论如何,释放 6 个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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.