繁体   English   中英

减少 memory 和 CPU 使用率

[英]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 分配,但是

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

  2. 即使您减小大小(而不是增加大小),也不一定会就地执行更改。 这意味着使用realloc可能比使用您描述的第一个策略更糟糕。 您最终可能会临时使用额外的 memory 和相同的复制成本,再加上 (1) 中描述的移动数组内容的成本。

  3. 无论如何,释放 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM