Я написал приложение, которое обрабатывает данные на GPU.Код работает хорошо, но у меня проблема в том, что считывающая часть входного файла (~ 3 ГБ, текст) является узким местом моего приложения.(Чтение с жесткого диска быстрое, но обработка строка за строкой медленная).
Я читаю строку с помощью getline () и копирую строку 1 в вектор, строку 2 в вектор и пропускаю строки 3 и4. И так далее для остальных 11 миллионов строк.
Я попробовал несколько подходов, чтобы получить файл в лучшее возможное время:
Самый быстрый метод, который я нашел, использует boost :: iostreams:: stream
Другие были:
- Чтение файла как gzip, чтобы минимизировать ввод-вывод, но медленнее, чем его непосредственное чтение.
- скопировать файл в оперативную память путем чтения (filepointer, chararray, length) и обработать его с помощью цикла, чтобы различать строки (также медленнее, чем 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.Это уменьшает время чтения и только минимально увеличивает время работы графического процессора.
Спасибо за ваши предложения.
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++;
}
}
}