【发布时间】:2014-12-20 14:13:02
【问题描述】:
我正在尝试使用缓存而不是使用缓存对磁盘 I/O 进行一些实验。为了直接从磁盘执行读取,我打开带有 O_DIRECT 标志的文件(定义变量 DISK_DIRECT)。
现在 if 下面的两个分支应该执行相同的操作,不同之处在于一个由缓存帮助,另一个没有。 我尝试访问的文件存储在磁盘上,并且不会随着时间而改变。 两个分支也访问相同的文件。
在这里的某个时候,当我使用 fread 时,我得到 ferror() 为真。而当我使用 read 时一切正常。
我确定他们访问的是相同的文件。 你知道为什么会发生这种情况吗?
编辑
好的,我在这里发布一个最小的例子。我使用的代码是:
#include <iostream>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#include <fstream>
#include <sstream>
using namespace std;
typedef float fftwf_complex [2] ;
void fetch_level(unsigned long long tid, unsigned short level, fftwf_complex* P_read, fftwf_complex* P_fread, int n_coeff_per_level, FILE** files_o_direct, fstream* & files) {
int b_read;
fseek(files_o_direct[level],(long int) (tid * sizeof(fftwf_complex)*n_coeff_per_level), SEEK_SET);
b_read = fread(reinterpret_cast<char*>(P_fread),sizeof(fftwf_complex), n_coeff_per_level,files_o_direct[level]);
if(b_read == 0){
cerr << "nothing read\n";
}
files[level].seekg((streamoff) (tid * sizeof(fftwf_complex)*n_coeff_per_level), files[level].beg);
files[level].read(reinterpret_cast<char*>(P_read),
sizeof(fftwf_complex) * n_coeff_per_level);
}
void open_files (fstream* & files){
for(int i=0; i<1;i++) {
std::ostringstream oss;
oss << "./Test_fread_read/1.txt.bin";
files[i].open(oss.str().c_str(),
std::ios::in | std::ios::out |
std::ios::binary | std::ios::ate);
if (!files[i])
{
cerr << "fstream could not open " << oss.str() << endl;
}
}
}
void open_files_o_direct (FILE** files_o_direct, int* fd){
for(unsigned int i=0;i<1; i++){
std::ostringstream oss;
oss << "./Test_fread_read/1.txt.bin";
fd[i]=open(oss.str().c_str(), O_RDONLY | O_DIRECT);
files_o_direct[i] = fdopen(fd[i], "rb");
if(!files_o_direct[i])
cerr << "Could not open " << oss.str() << endl;
}
}
int close_files(FILE** files_o_direct, int* fd, fstream* & files) {
for(unsigned int i=0; i<1; i++){
//#if defined (DISK_DIRECT)
if(files_o_direct[i])
close(fd[i]);
//#else
if(files[i].is_open())
files[i].close();
//#endif
}
return 0;
}
int main(){
FILE**files_o_direct = new FILE* [256];
fstream* files = new fstream [256];
int * fd = new int [256];
fftwf_complex * P_read = new fftwf_complex [1];
fftwf_complex * P_fread = new fftwf_complex [1];
open_files_o_direct(files_o_direct, fd);
open_files(files);
fetch_level(2, 0, P_read, P_fread, 1, files_o_direct, files);
cout << "P_read: " << P_read[0][0] << " P_fread: " << P_fread[0][0] << endl;
cout << "P_read: " << P_read[0][1] << " P_fread: " << P_fread[0][1] << endl;
fetch_level(7, 0, P_read, P_fread, 1, files_o_direct, files);
cout << "P_read: " << P_read[0][0] << " P_fread: " << P_fread[0][0] << endl;
cout << "P_read: " << P_read[0][1] << " P_fread: " << P_fread[0][1] << endl;
fetch_level(8, 0, P_read, P_fread, 1, files_o_direct, files);
cout << "P_read: " << P_read[0][0] << " P_fread: " << P_fread[0][0] << endl;
cout << "P_read: " << P_read[0][1] << " P_fread: " << P_fread[0][1] << endl;
close_files(files_o_direct, fd, files);
delete [] P_read;
delete [] P_fread;
delete [] files;
delete [] files_o_direct;
return 0;
}
访问的文件是:
0.133919 0.0458176
1.67441 2.40805
0.997525 -0.279977
-2.39672 -3.076
-0.0390913 0.854464
-0.0176478 -1.3142
-0.667981 -0.486272
0.831051 0.282802
-0.638032 -0.630943
-0.669854 -1.49762
以二进制格式存储,可从here: 1.txt.bin下载。
我得到的输出是:
nothing read
P_read: 0.997525 P_fread: 0
P_read: -0.279977 P_fread: 0
nothing read
P_read: 0.831051 P_fread: 0
P_read: 0.282802 P_fread: 0
nothing read
P_read: -0.638032 P_fread: 0
P_read: -0.630943 P_fread: 0
即使我将 fftwf_complex 的类型从 float[2] 更改为 simple float,问题仍然存在。 如果我删除 fseek 行一切正常。
【问题讨论】:
-
错误号是多少?你检查了吗?
-
MCVE 将在很大程度上证明您遇到的问题,并且鉴于您的主张
fread与std::istream::read是唯一的区别,提供微不足道的。发布的代码不仅不可编译,而且不是范围平衡的。fread调用在}之前包含fseek和fread。std::istream::seekg和std::istream::read之间有一个}。显然你遗漏了something。 -
我尝试使用 explain_fread 但出现“未定义引用”错误,我不知道是不是因为您需要链接库,但我没有找到任何关于那。还有其他方法可以获取错误号吗?
-
@WhozCraig 这是一个错字,我已经更正了
-
@Sergio “我尝试使用 explain_fread ...” 你甚至没有在你的问题中提到这一点。您是否查看了此问答如何解决该问题:stackoverflow.com/questions/12573816/…