我正在阅读一个文件,里面有元组的数量" n_tups"单个元组的长度或其长度" d"是输入。对于二维数组" tuple"我已按如下方式分配内存。
当我运行代码时,我的计算机挂起,我不知道为什么。
if((fpp = fopen("in2.bin", "rb"))==NULL)
printf("file in2.bin doesn't exist!");
else
{
int **tuple;
unsigned long i;
tuple = malloc(n_tups * sizeof(int *));
if(tuple == NULL)
{
fprintf(stderr, "out of memory\n");
return;
}
for(i=0;i<n_tups;i++){
tuple[i]=malloc(d * sizeof(int));
if(tuple[i] == NULL)
{
fprintf(stderr, "out of memory\n");
return;
}
}
fseek( fpp , 0 , SEEK_SET );
printf("reading step");
for(i=0;i<n_tups;i++){
fread(&tuple[i],4,d,fpp);
fread(&score[i],8,1,fpp);
}
fclose(fpp);
}
我试图检查程序是否到达&#34;阅读步骤&#34;它没有。原来忙于分配内存! 我通过d = 3 n_tups = 85013600,我的电脑有4 GB的RAM。
答案 0 :(得分:4)
代码本身存在两个性能问题。
即使所有维度都相同,您也会不必要地使用指向指针的查找表。使用2D数组会好得多,因此所有数据都分配在相邻的内存中。这样,CPU不必每次读取堆都会挖掘RAM,而是可以利用数据缓存内存。
像这样:
int (*tuple)[d] = malloc( sizeof(int[n_tups][d]) );
...
free(tuple);
每次拨打fread
都会很费劲。尝试每次调用尽可能读取大块。在你的情况下,什么是最佳的,我不知道 - 它是系统依赖的。但是将其称为小块数据将无效。特别是因为正确编写的程序将始终检查每个fread
调用的结果。
理想情况下,假设您遵循我之前关于使用2D阵列的建议,您只需要这样做:
result = fread(tuple, sizeof(int[n_tups][d]), 1, fpp);
但是,该文件似乎包含您希望存储在其他位置的无关数据。考虑使用单个结构数组替换两个int
数组,这样您每次都可以读取更长的内存块。 (但是,请注意构造填充。)
请注意,从磁盘读取非常大的数据块可能非常耗时,因此请考虑从其他线程而不是主(GUI?)线程执行此操作。