每个原始数据为512*512的一个矩阵。如果进行基线检查(每个矩阵元减去一个背景值),那么数据为一个大概1000-2000个点的稀疏矩阵。如果不进行基线检查,就是原始矩阵512*512个点。
如果要实现数据的实时保存,请问采用什么方法比较好?非常感谢!下面是我用的方法,但是发现耗时严重每秒大概2次不到的样子。CPU:intel i5-6500@3.2GHz,16GB内存。
for (int jj=0;jj<1000;jj++) {
char* filename;
filename = char(jj);
FILE *f = fopen( filename, "w" );
for (y=0; y<ny; y++) {
float *ptr = (float*)GetPtr(bufnum,y);
for (x=0; x<nx; x++, ptr++)
fprintf(f,"%*.3f ",12, *ptr);
fprintf(f,"\n");
}
}
fclose(f);
10 个解决方案
#1
你这代码本身就有问题啊,在循环体里边执行fopen,却在循环体外边fclose,没有配对。fopen应该在循环之前做。
#2
你的文件打开次数太多了吧
你要打开几个文件?看你的打开文件在一个循环里,那么应该是打开多次(或打开多个文件)。如果实时保存时,只需要保存一份数据,建议先把文件打开再循环写入。另外,再次写入时将文件指针,只需要将文件指针重新指向文件开头即可。使用fseek或者rewind都可以实现将文件指针指向文件开始位置
for (int jj=0;jj<1000;jj++) {
char* filename;
filename = char(jj);
FILE *f = fopen( filename, "w" );
for (y=0; y<ny; y++) {
float *ptr = (float*)GetPtr(bufnum,y);
for (x=0; x<nx; x++, ptr++)
fprintf(f,"%*.3f ",12, *ptr);
fprintf(f,"\n");
}
}
你要打开几个文件?看你的打开文件在一个循环里,那么应该是打开多次(或打开多个文件)。如果实时保存时,只需要保存一份数据,建议先把文件打开再循环写入。另外,再次写入时将文件指针,只需要将文件指针重新指向文件开头即可。使用fseek或者rewind都可以实现将文件指针指向文件开始位置
#3
打开文件会比较耗时,所以若是循环打开或者打开多个文件耗时就更多了。
#4
谢谢大家回复,重新编辑了一下. 因为数据量比较大,担心CPU运行不过来,所以打算每次都把数据保存下来,保存到不到的文件中。
for (int jj=0;jj<1000;jj++) // 采集1000次
{
char* filename; //每一次的文件名
filename = char(jj);//每一次的文件名
FILE *f = fopen( filename, "w" ); //每次保存一个新文件
for (y=0; y<ny; y++) {
float *ptr = (float*)GetPtr(bufnum,y);
for (x=0; x<nx; x++, ptr++)
fprintf(f,"%*.3f ",12, *ptr); //把数据写入新文件
fprintf(f,"\n");
}
fclose(f); //数据采集完一次,关闭文件;
}
for (int jj=0;jj<1000;jj++) // 采集1000次
{
char* filename; //每一次的文件名
filename = char(jj);//每一次的文件名
FILE *f = fopen( filename, "w" ); //每次保存一个新文件
for (y=0; y<ny; y++) {
float *ptr = (float*)GetPtr(bufnum,y);
for (x=0; x<nx; x++, ptr++)
fprintf(f,"%*.3f ",12, *ptr); //把数据写入新文件
fprintf(f,"\n");
}
fclose(f); //数据采集完一次,关闭文件;
}
#5
由于C语言不能获得足够的权限,C程序是做成dll文件被其他程序调用使用的。不知道下面这个替代方法是否可行。
1,指定一个较大的内存区域,用于不停的存储新来的数据。
2. 主程序每调用一次C程序(dll文件),就在内存中进行一次基线检查,然后将剩下的矩阵元(1000个点)写入1中开辟的内存中。
并保证内存空间中的数据不消失(怎么保证?)
3.多次采集后例如(10万次后,将内存中的数据一次性写入硬盘)
由于每次主程序调用的是dll文件,每次调用完之后,dll文件都关闭了,那怎么保证内存空间中的数据不消失?
非常谢谢!
1,指定一个较大的内存区域,用于不停的存储新来的数据。
2. 主程序每调用一次C程序(dll文件),就在内存中进行一次基线检查,然后将剩下的矩阵元(1000个点)写入1中开辟的内存中。
并保证内存空间中的数据不消失(怎么保证?)
3.多次采集后例如(10万次后,将内存中的数据一次性写入硬盘)
由于每次主程序调用的是dll文件,每次调用完之后,dll文件都关闭了,那怎么保证内存空间中的数据不消失?
非常谢谢!
#6
// 创建文件句柄
HANDLE hFile = ::CreateFile(lpszFileName, GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
// 创建文件映射
HANDLE hMap = ::CreateFileMapping(hFile, NULL, PAGE_READONLY | SEC_COMMIT, NULL, NULL, NULL);
// 读取映射中的内存
LPVOID lpBuffer = ::MapViewOfFile(hMap, FILE_MAP_READ, NULL, NULL, NULL);
// 好了文件的内存已经获取了,你可以随意处理了
// 释放映射内存
::UnmapViewOfFile(lpBuffer);
// 关闭文件映射
::CloseHandle(hMap);
// close file handle
::CloseHandle(hFile);
HANDLE hFile = ::CreateFile(lpszFileName, GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
// 创建文件映射
HANDLE hMap = ::CreateFileMapping(hFile, NULL, PAGE_READONLY | SEC_COMMIT, NULL, NULL, NULL);
// 读取映射中的内存
LPVOID lpBuffer = ::MapViewOfFile(hMap, FILE_MAP_READ, NULL, NULL, NULL);
// 好了文件的内存已经获取了,你可以随意处理了
// 释放映射内存
::UnmapViewOfFile(lpBuffer);
// 关闭文件映射
::CloseHandle(hMap);
// close file handle
::CloseHandle(hFile);
#7
// 创建文件句柄
HANDLE hFile = ::CreateFile(lpszFileName, GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
// 创建文件映射
HANDLE hMap = ::CreateFileMapping(hFile, NULL, PAGE_READONLY | SEC_COMMIT, NULL, NULL, NULL);
// 读取映射中的内存
LPVOID lpBuffer = ::MapViewOfFile(hMap, FILE_MAP_READ, NULL, NULL, NULL);
// 好了文件的内存已经获取了,你可以随意处理了
// 释放映射内存
::UnmapViewOfFile(lpBuffer);
// 关闭文件映射
::CloseHandle(hMap);
// close file handle
::CloseHandle(hFile);
#8
嗯。。稀疏矩阵最好用位图bitmap,可以去自己参考一下思想。空间利用率和CPU利用率都很高
如果想进一步压缩时间的话,最好减少IO的操作次数,考虑把成堆数据一次性输出到文件中
最后,将数据从内存中输出到硬盘中的操作,是不怎么会用到CPU的,电脑自带存储管理管线和控制器,CPU只是吧数据放在控制器上而已,传输操作不归CPU管
如果想进一步压缩时间的话,最好减少IO的操作次数,考虑把成堆数据一次性输出到文件中
最后,将数据从内存中输出到硬盘中的操作,是不怎么会用到CPU的,电脑自带存储管理管线和控制器,CPU只是吧数据放在控制器上而已,传输操作不归CPU管
#9
内存中的数据只要你程序没有崩溃或者关闭,就会一直存在,所以你要做的,就是写一个好的、鲁棒的程序,保证其稳定性,
#10
你代码本身就存在问题,你打开了多次fopen,如果你想向一个文件中紧接文件尾部继续写入可以用fflush
#1
你这代码本身就有问题啊,在循环体里边执行fopen,却在循环体外边fclose,没有配对。fopen应该在循环之前做。
#2
你的文件打开次数太多了吧
你要打开几个文件?看你的打开文件在一个循环里,那么应该是打开多次(或打开多个文件)。如果实时保存时,只需要保存一份数据,建议先把文件打开再循环写入。另外,再次写入时将文件指针,只需要将文件指针重新指向文件开头即可。使用fseek或者rewind都可以实现将文件指针指向文件开始位置
for (int jj=0;jj<1000;jj++) {
char* filename;
filename = char(jj);
FILE *f = fopen( filename, "w" );
for (y=0; y<ny; y++) {
float *ptr = (float*)GetPtr(bufnum,y);
for (x=0; x<nx; x++, ptr++)
fprintf(f,"%*.3f ",12, *ptr);
fprintf(f,"\n");
}
}
你要打开几个文件?看你的打开文件在一个循环里,那么应该是打开多次(或打开多个文件)。如果实时保存时,只需要保存一份数据,建议先把文件打开再循环写入。另外,再次写入时将文件指针,只需要将文件指针重新指向文件开头即可。使用fseek或者rewind都可以实现将文件指针指向文件开始位置
#3
打开文件会比较耗时,所以若是循环打开或者打开多个文件耗时就更多了。
#4
谢谢大家回复,重新编辑了一下. 因为数据量比较大,担心CPU运行不过来,所以打算每次都把数据保存下来,保存到不到的文件中。
for (int jj=0;jj<1000;jj++) // 采集1000次
{
char* filename; //每一次的文件名
filename = char(jj);//每一次的文件名
FILE *f = fopen( filename, "w" ); //每次保存一个新文件
for (y=0; y<ny; y++) {
float *ptr = (float*)GetPtr(bufnum,y);
for (x=0; x<nx; x++, ptr++)
fprintf(f,"%*.3f ",12, *ptr); //把数据写入新文件
fprintf(f,"\n");
}
fclose(f); //数据采集完一次,关闭文件;
}
for (int jj=0;jj<1000;jj++) // 采集1000次
{
char* filename; //每一次的文件名
filename = char(jj);//每一次的文件名
FILE *f = fopen( filename, "w" ); //每次保存一个新文件
for (y=0; y<ny; y++) {
float *ptr = (float*)GetPtr(bufnum,y);
for (x=0; x<nx; x++, ptr++)
fprintf(f,"%*.3f ",12, *ptr); //把数据写入新文件
fprintf(f,"\n");
}
fclose(f); //数据采集完一次,关闭文件;
}
#5
由于C语言不能获得足够的权限,C程序是做成dll文件被其他程序调用使用的。不知道下面这个替代方法是否可行。
1,指定一个较大的内存区域,用于不停的存储新来的数据。
2. 主程序每调用一次C程序(dll文件),就在内存中进行一次基线检查,然后将剩下的矩阵元(1000个点)写入1中开辟的内存中。
并保证内存空间中的数据不消失(怎么保证?)
3.多次采集后例如(10万次后,将内存中的数据一次性写入硬盘)
由于每次主程序调用的是dll文件,每次调用完之后,dll文件都关闭了,那怎么保证内存空间中的数据不消失?
非常谢谢!
1,指定一个较大的内存区域,用于不停的存储新来的数据。
2. 主程序每调用一次C程序(dll文件),就在内存中进行一次基线检查,然后将剩下的矩阵元(1000个点)写入1中开辟的内存中。
并保证内存空间中的数据不消失(怎么保证?)
3.多次采集后例如(10万次后,将内存中的数据一次性写入硬盘)
由于每次主程序调用的是dll文件,每次调用完之后,dll文件都关闭了,那怎么保证内存空间中的数据不消失?
非常谢谢!
#6
// 创建文件句柄
HANDLE hFile = ::CreateFile(lpszFileName, GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
// 创建文件映射
HANDLE hMap = ::CreateFileMapping(hFile, NULL, PAGE_READONLY | SEC_COMMIT, NULL, NULL, NULL);
// 读取映射中的内存
LPVOID lpBuffer = ::MapViewOfFile(hMap, FILE_MAP_READ, NULL, NULL, NULL);
// 好了文件的内存已经获取了,你可以随意处理了
// 释放映射内存
::UnmapViewOfFile(lpBuffer);
// 关闭文件映射
::CloseHandle(hMap);
// close file handle
::CloseHandle(hFile);
HANDLE hFile = ::CreateFile(lpszFileName, GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
// 创建文件映射
HANDLE hMap = ::CreateFileMapping(hFile, NULL, PAGE_READONLY | SEC_COMMIT, NULL, NULL, NULL);
// 读取映射中的内存
LPVOID lpBuffer = ::MapViewOfFile(hMap, FILE_MAP_READ, NULL, NULL, NULL);
// 好了文件的内存已经获取了,你可以随意处理了
// 释放映射内存
::UnmapViewOfFile(lpBuffer);
// 关闭文件映射
::CloseHandle(hMap);
// close file handle
::CloseHandle(hFile);
#7
// 创建文件句柄
HANDLE hFile = ::CreateFile(lpszFileName, GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
// 创建文件映射
HANDLE hMap = ::CreateFileMapping(hFile, NULL, PAGE_READONLY | SEC_COMMIT, NULL, NULL, NULL);
// 读取映射中的内存
LPVOID lpBuffer = ::MapViewOfFile(hMap, FILE_MAP_READ, NULL, NULL, NULL);
// 好了文件的内存已经获取了,你可以随意处理了
// 释放映射内存
::UnmapViewOfFile(lpBuffer);
// 关闭文件映射
::CloseHandle(hMap);
// close file handle
::CloseHandle(hFile);
#8
嗯。。稀疏矩阵最好用位图bitmap,可以去自己参考一下思想。空间利用率和CPU利用率都很高
如果想进一步压缩时间的话,最好减少IO的操作次数,考虑把成堆数据一次性输出到文件中
最后,将数据从内存中输出到硬盘中的操作,是不怎么会用到CPU的,电脑自带存储管理管线和控制器,CPU只是吧数据放在控制器上而已,传输操作不归CPU管
如果想进一步压缩时间的话,最好减少IO的操作次数,考虑把成堆数据一次性输出到文件中
最后,将数据从内存中输出到硬盘中的操作,是不怎么会用到CPU的,电脑自带存储管理管线和控制器,CPU只是吧数据放在控制器上而已,传输操作不归CPU管
#9
内存中的数据只要你程序没有崩溃或者关闭,就会一直存在,所以你要做的,就是写一个好的、鲁棒的程序,保证其稳定性,
#10
你代码本身就存在问题,你打开了多次fopen,如果你想向一个文件中紧接文件尾部继续写入可以用fflush