Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 动态分配速度问题_C_Arrays_Performance_Dynamic_Malloc - Fatal编程技术网

C 动态分配速度问题

C 动态分配速度问题,c,arrays,performance,dynamic,malloc,C,Arrays,Performance,Dynamic,Malloc,我正在使用以下代码动态创建二维阵列: char **FileTables; int rows = 1000; int i; FileTables = (char**)malloc(rows * sizeof(char)); for (i = 0; i < rows; i++) { FileTables[i] = (char*)malloc(256 * sizeof(char)); } (是的,我修复了不必要的施法)您只需两次分配和一些指针运算即可: int rows = 100

我正在使用以下代码动态创建二维阵列:

char **FileTables;
int rows = 1000;
int i;

FileTables = (char**)malloc(rows * sizeof(char));
for (i = 0; i < rows; i++) {
    FileTables[i] = (char*)malloc(256 * sizeof(char));
}

(是的,我修复了不必要的施法)

您只需两次分配和一些指针运算即可:

int rows = 1000;
int cols = 256;
char *data;
char **FileTables;
int i;

data = malloc(rows * cols);
FileTables = malloc(rows * sizeof(char*));
for (i = 0; i < rows; i++) {
    FileTables[i] = data + i * cols;
}
int行=1000;
int cols=256;
字符*数据;
字符**文件表;
int i;
数据=malloc(行*列);
FileTables=malloc(rows*sizeof(char*));
对于(i=0;i

也注意到我在代码< > Maloc(行*sieZOF(char))< /C>(代码< > CIER(char)< /C> >中应该修复了一个bug,应该是<代码> siZeof(char)< /C> >,因为您正在分配一个指针数组,阿纳尔> < p> >代码> > p> >如果数组总是大小为代码>行< /代码>×256,那么您可以考虑一维数组<代码> Maloc(行* 256)。,并可快速访问:

char get(unsigned i, unsigned j, char * array) { return array[j + 256 * i]; }
void set(char value, unsigned i, unsigned j, char * array) { array[j + 256 * i] = value; }
这避免了多次分配,并提供了更好的内存局部性。除此之外,您还可以选择行或列顺序进行微优化。

char**FileTables;
char **FileTables; 
int rows = 1000; 
int i; 

FileTables = (char**)malloc(rows * sizeof(char *)); 
char *data = (char *)malloc(256 * 1000 * sizeof(char));
for (i = 0; i < rows; ++i) { 
    FileTables[i] = data;
    data += 256 * sizeof(char);
}
int行=1000; int i; FileTables=(char**)malloc(rows*sizeof(char*); char*data=(char*)malloc(256*1000*sizeof(char)); 对于(i=0;i

应该是更好的解决方案。

首先,您确定内存分配是问题所在吗?分配1000块内存通常不需要几秒钟

如果您有特殊需求,您可以研究其他malloc实现(例如,如果您在线程中分配内存,则可以使用google的tcmalloc)


否则,malloc真正“慢”的部分实际上是从操作系统获取内存(使用sbrk()或mmap()),大多数malloc实现会一次获取一大块内存,然后以较小的部分返回,因此这里没有1000个调用分配1k,可能有60个调用分配16k。在strace或类似模式下运行该程序可能会让您了解实际进行了多少缓慢的系统调用。。您可以自己实现类似的行为,只需调用一次就可以分配256K并将其细分为更小的块。您可以尝试分配一大块内存,然后立即释放(),并希望库malloc保留该内存,而不是返回操作系统获取更多内存。

这看起来真的像是过早优化;因为,你要求更快,但你没有指出有多快才算足够快。不过,如果你真的需要这样做

加快分配的提示:

  • 减少分配
  • 进行较小的分配
  • 正如您所看到的,如果您需要1000万美元,这些提示很快就会发生冲突。要在较小的分配和较少的分配之间确定正确的平衡,on需要进行分析

    查看内存块大小,立即分配整个内存页。这是一个古老的硬件攻击,但它确实保证了您不会一次请求多页连续内存(这加快了从空闲页列表中选择的速度),而且它还保证您不会因为请求内存管理器的块保留子系统已经保留的地址而浪费一些周期地址空间

    如果这并不能获得所需的性能,那么重写代码,使其不需要按照原来的方式分配


    无论哪种方式,如果不详细了解计算机上内存管理子系统的实际设计,就无法保证最佳分配速度。

    只要列数不变,或者如果使用C99,您可以使用单个
    malloc
    ,而无需自己执行难看的行/列寻址算法:

    char (*FileTables)[256] = malloc(rows * sizeof *FileTables);
    

    我不相信你能在几秒钟内到达任何地方。在我的机器上,将行数增加到1000万仍然不到一秒钟

    然而,如果你想最小化分配,你只需要一个

    FileTables = (char**) malloc(rows * (sizeof(char *) + 256*sizeof(char)));
    FileTables[0] = (char *) &FileTables[rows];
    for (i = 1; i < rows; i++) {
        FileTables[i] = FileTables[i-1] + 256 * sizeof (char);
    }
    free(FileTables);
    

    这避免了指针查找,因为C可以计算其余部分。

    注意:您不应该在C中强制转换malloc的结果-这是不必要的,并且可能会掩盖编译器可能警告您的错误。Paul:+1。我真想知道为什么人们会这样做。他们在什么时候说,“嗯,我的代码运行得很好,看起来很棒。我想知道我是否可以通过插入免费的强制转换来给它添加一些噪音。
    对于(I=(int)0;(int)I<12;++(int)I)
    @Kerrek:
    ++(int)I
    不编译。
    ++
    需要左值而
    (int)i
    不是左值。保罗:是的,的确,这是一个过度夸张的例子。公平地说,malloc类型转换通常也会改变类型——但不必要的是,因为转换已经是隐式的。注意(注释已删除).1作为答案。我本来打算使用aix发布的解决方案,但这要简单得多,代码也少得多。有人能评论一下哪种方法更好,为什么?我更喜欢我的方法,因为
    FileTables
    的类型是正确的,您可以只编写
    FileTables[row][col
    FileTables[row]
    本身将衰减为指向该行的指针(一个普通的
    char*
    )。您不必自己跟踪算术。我是用通常的
    free(FileTables);
    释放它,还是需要做一些特殊的事情?没错,就是
    free(FileTables);
    。您也可以在其上使用
    realloc
    ;只需确保正确计算新尺寸即可。
    char (*FileTables)[256] = malloc(rows * sizeof *FileTables);
    
    FileTables = (char**) malloc(rows * (sizeof(char *) + 256*sizeof(char)));
    FileTables[0] = (char *) &FileTables[rows];
    for (i = 1; i < rows; i++) {
        FileTables[i] = FileTables[i-1] + 256 * sizeof (char);
    }
    free(FileTables);
    
    typedef char chars[256];
    
    int main(int argc, char** argv) {
        chars* FileTables;
        int rows = 100000000;
        int i;
    
        FileTables = (chars*) malloc(rows * sizeof (chars));
        free(FileTables);
    
        return (EXIT_SUCCESS);
    }