Как обработать большой файл за минимальное время (c ++, openmp, входной файл: FASTQ / FASTA) - PullRequest
0 голосов
/ 27 декабря 2018

У меня есть многопоточное приложение (OpenMP), в котором мы читаем очень большой файл размером (10 - 350 ГБ), содержащий геномные чтения (строки).Из-за ограниченного объема ОЗУ (8 ГБ) мы пытаемся обработать этот большой входной файл в виде кусков, где мы помещаем в вектор некоторое число х строк и обрабатываем его, используя несколько потоков.Этот процесс повторяется, пока все строки во входном файле не будут полностью обработаны.Но этот подход очень медленный.Мы даже протестировали код, изменив размер массива (1000000 строк), но он потребовал больше времени, чем массив размером 1000. Как я могу оптимизировать его с точки зрения времени?

SAMPLE CODE:

#include <zlib.h>
#include <stdio.h>
#include "kseq.h"
#include <string>
#include <vector>
#include <iostream>
#include <omp.h>
int main()
{
    gzFile fp;
    kseq_t *seq;
    int l;
    int it;
    int read_count=0;
    fp = gzopen("dm.fastq", "r");
    seq = kseq_init(fp);
    vector <string> array;       
 while ((l = kseq_read(seq)) >= 0) 
    {
            if (read_count <= 999) 
        {
                array.push_back(seq->seq.s);
                read_count++;
        }
            if (read_count == 1000) 
        {
        #pragma omp parallel for num_threads(12) schedule(static) private(it) shared(array)
                for (it = 0; it < array.size(); ++it) 
            {
                string line = array[it];
                            int size_s = line.size();
                            char _buf[size_s + 1];
                            strcpy(_buf, line.c_str());
            }
        array.clear();    
        read_count=0;
        }
    }
    #pragma omp parallel for num_threads(12) schedule(static) private(it) shared(array)
        for (it = 0; it < array.size(); ++it) 
            {
                            string line = array[it];
                            int size_s = line.size();
                            char _buf[size_s + 1];
                            strcpy(_buf, line.c_str());
            }
    
    kseq_destroy(seq);gzclose(fp);return 0;
}//main close

1 Ответ

0 голосов
/ 31 декабря 2018

Во-первых, вы должны знать, что при считывании (без обработки) со стандартного вращающегося жесткого диска файл объемом 100 ГБ должен занимать около 17 минут.

Во-вторых, о вашем коде - в тех местах, где это происходит, есть openmp.не имеет значения и не имеет операций (strcpy(_buf один).Этот цикл для не требует так много процессора для его распараллеливания.Возможно, это всего лишь пример, но это имеет значение.

И, наконец, большая часть (например, 90%) ЦП потребляется в библиотеке ( kseq_read ) и gzopen (и кажется, что ваши файлы размером 100 ГБ сжаты).

...