【发布时间】:2011-12-28 17:09:47
【问题描述】:
我编写了一个在 GPU 上处理数据的应用程序。代码运行良好,但我的问题是输入文件的读取部分(~3GB,文本)是我的应用程序的瓶颈。 (从硬盘读取速度很快,但逐行处理很慢)。
我用 getline() 读取了一行并将第 1 行复制到一个向量,将第 2 行复制到一个向量并跳过第 3 行和第 4 行。对于其余 11 行 mio 行,依此类推。
我尝试了几种方法以尽可能在最佳时间获取文件:
我发现最快的方法是使用 boost::iostreams::stream
其他人是:
- 以 gzip 格式读取文件,以最小化 IO,但比直接慢 阅读它。
- 通过读取将文件复制到内存(文件指针、字符数组、长度) 并用循环处理它以区分行(也比 boost 慢)
有什么建议可以让它运行得更快吗?
void readfastq(char *filename, int SRlength, uint32_t blocksize){
_filelength = 0; //total datasets (each 4 lines)
_SRlength = SRlength; //length of the 2. line
_blocksize = blocksize;
boost::iostreams::stream<boost::iostreams::file_source>ins(filename);
in = ins;
readNextBlock();
}
void readNextBlock() {
timeval start, end;
gettimeofday(&start, 0);
string name;
string seqtemp;
string garbage;
string phredtemp;
_seqs.empty();
_phred.empty();
_names.empty();
_filelength = 0;
//read only a part of the file i.e the first 4mio lines
while (std::getline(in, name) && _filelength<_blocksize) {
std::getline(in, seqtemp);
std::getline(in, garbage);
std::getline(in, phredtemp);
if (seqtemp.size() != _SRlength) {
if (seqtemp.size() != 0)
printf("Error on read in fastq: size is invalid\n");
} else {
_names.push_back(name);
for (int k = 0; k < _SRlength; k++) {
//handle special letters
if(seqtemp[k]== 'A') ...
else{
_seqs.push_back(5);
}
}
_filelength++;
}
}
编辑:
源文件可在https://docs.google.com/open?id=0B5bvyb427McSMjM2YWQwM2YtZGU2Mi00OGVmLThkODAtYzJhODIzYjNhYTY2下下载
由于一些指针问题,我更改了函数 readfastq 来读取文件。因此,如果您调用readfastq,blocksize(以行为单位)必须大于要读取的行数。
解决方案:
我找到了一个解决方案,它将读取文件的时间从 60 秒缩短到 16 秒。我删除了处理特殊字符的内循环并在 GPU 中执行此操作。这减少了读入时间,并且仅略微增加了 GPU 运行时间。
感谢您的建议。
void readfastq(char *filename, int SRlength) {
_filelength = 0;
_SRlength = SRlength;
size_t bytes_read, bytes_expected;
FILE *fp;
fp = fopen(filename, "r");
fseek(fp, 0L, SEEK_END); //go to the end of file
bytes_expected = ftell(fp); //get filesize
fseek(fp, 0L, SEEK_SET); //go to the begining of the file
fclose(fp);
if ((_seqarray = (char *) malloc(bytes_expected/2)) == NULL) //allocate space for file
err(EX_OSERR, "data malloc");
string name;
string seqtemp;
string garbage;
string phredtemp;
boost::iostreams::stream<boost::iostreams::file_source>file(filename);
while (std::getline(file, name)) {
std::getline(file, seqtemp);
std::getline(file, garbage);
std::getline(file, phredtemp);
if (seqtemp.size() != SRlength) {
if (seqtemp.size() != 0)
printf("Error on read in fastq: size is invalid\n");
} else {
_names.push_back(name);
strncpy( &(_seqarray[SRlength*_filelength]), seqtemp.c_str(), seqtemp.length()); //do not handle special letters here, do on GPU
_filelength++;
}
}
}
【问题讨论】:
-
“ram”是指 PC 内存,还是板载视频内存?
-
请注意,
string::empty()和vector::empty()是对容器状态的只读测试。也许你的意思是.clear()? -
_seqs.empty();只返回true。默认构造函数创建一个空字符串,bool std::string::empty() const和void std::string::clear()不一样。 -
我不知道您要解决的问题,但您确定文本文件是处理如此庞大的数据集和显然时间紧迫的应用程序的方法吗?