For loop 如何使用OpenMP并行读取每四行.gz文件? test.fa.gz文件包含多个4行,如下所示: @HWI-ST298:420:B08APABXX:3:1101:1244:2212 1:N:0:TCATTC GGCAAGGCTACTTTACAGTAAGAGAGAGAGTCAGC + @@@FDFFDFHCFDACGHC

For loop 如何使用OpenMP并行读取每四行.gz文件? test.fa.gz文件包含多个4行,如下所示: @HWI-ST298:420:B08APABXX:3:1101:1244:2212 1:N:0:TCATTC GGCAAGGCTACTTTACAGTAAGAGAGAGAGTCAGC + @@@FDFFDFHCFDACGHC,for-loop,openmp,filehandle,gzip,For Loop,Openmp,Filehandle,Gzip,getline函数不是线程安全的。因此,如果没有未定义的行为,就无法从不同线程同时调用它。正确执行此操作的唯一方法是围绕每个getline调用创建关键部分,强制在任何时候只有一个线程在“gz”上调用getline。然而,在您的代码示例中,我怀疑使用多个线程会有任何加速,因为除了读取“gz”中的行之外,线程没有多少工作要做 getline函数不是线程安全的。因此,如果没有未定义的行为,就无法从不同线程同时调用它。正确执行此操作的唯一方法是围绕每个getline调用创建关键部分,强制在任何时候只有一

getline函数不是线程安全的。因此,如果没有未定义的行为,就无法从不同线程同时调用它。正确执行此操作的唯一方法是围绕每个getline调用创建关键部分,强制在任何时候只有一个线程在“gz”上调用getline。然而,在您的代码示例中,我怀疑使用多个线程会有任何加速,因为除了读取“gz”中的行之外,线程没有多少工作要做

getline函数不是线程安全的。因此,如果没有未定义的行为,就无法从不同线程同时调用它。正确执行此操作的唯一方法是围绕每个getline调用创建关键部分,强制在任何时候只有一个线程在“gz”上调用getline。然而,在您的代码示例中,我怀疑使用多个线程会有任何加速,因为除了读取“gz”中的行之外,线程没有多少工作要做

与其说是答案,不如说是一个延伸的评论,但不管怎样

即使
getline
是线程安全的,在OpenMP程序中让多个线程同时读取同一个文件也可能不是一个好主意。除非您有一个并行文件系统(因为您没有提到它,所以我假设您没有),否则您就有可能编写一个程序,其中线程为单个I/O通道而相互争斗。考虑4个线程的情况,每个线程读取文件的不同部分,全部使用磁盘上的1个读/写头。准随机读取一个文件的小部分可能是你能想到的最慢的方法

Haatschi建议将文件访问包装在一个关键部分中,这只意味着线程不会为I/O访问而斗争,而是友好地一起玩,每个线程都礼貌地等待轮到它。但是,正如Haatschi所建议的,这不太可能导致文件读取的任何加速,更可能(以我的经验)导致文件读取的速度减慢。如果I/O时间不重要,那么这可能是一种方法


如果您关心I/O时间,那么要么在一个线程中读取文件,然后并行处理数据;或者,让每个线程一次从文件中读取所有数据,使用关键部分避免I/O资源争用

可能更多的是一个扩展注释而不是答案,但无论如何

即使
getline
是线程安全的,在OpenMP程序中让多个线程同时读取同一个文件也可能不是一个好主意。除非您有一个并行文件系统(因为您没有提到它,所以我假设您没有),否则您就有可能编写一个程序,其中线程为单个I/O通道而相互争斗。考虑4个线程的情况,每个线程读取文件的不同部分,全部使用磁盘上的1个读/写头。准随机读取一个文件的小部分可能是你能想到的最慢的方法

Haatschi建议将文件访问包装在一个关键部分中,这只意味着线程不会为I/O访问而斗争,而是友好地一起玩,每个线程都礼貌地等待轮到它。但是,正如Haatschi所建议的,这不太可能导致文件读取的任何加速,更可能(以我的经验)导致文件读取的速度减慢。如果I/O时间不重要,那么这可能是一种方法


如果您关心I/O时间,那么要么在一个线程中读取文件,然后并行处理数据;或者,让每个线程一次从文件中读取所有数据,使用关键部分避免I/O资源争用

如果getline()无法加速,是否还有其他函数可以使用OpenMp加速读取文件?谢谢。我不认为使用多个线程来简单地将文件读入ram会有可能的加速。然而,如果你使用你读到的数据,当然会有。在这种情况下,将getline放在一个关键部分并并行地完成“工作”是有意义的。如果您的“reverseStrand”需要大量计算时间,您可以尝试这样做。如果getline()无法加速,是否有其他函数可以加速OpenMp读取文件?谢谢。我不认为使用多个线程来简单地将文件读入ram会有可能的加速。然而,如果你使用你读到的数据,当然会有。在这种情况下,将getline放在一个关键部分并并行地完成“工作”是有意义的。如果您的“reverseStrand”需要大量计算时间,您可以尝试这样做。即使他有一个并行文件系统,他也从一个压缩文件中读取,该压缩文件本质上是可并行撤消的(除非文件以块压缩并提供索引…),即使他有一个并行文件系统,他正在读取一个压缩文件,该文件本来是可并行撤消的(除非该文件以块压缩且提供了索引…),即使原始未压缩内容由大小相同的记录组成,也无法并行读取压缩文件。您必须使用关键部分串行化I/O,这将从根本上失去并行处理的好处。在一个线程中尽可能多地读取文件,然后并行处理已读取的内容,然后重复,直到EOF。即使原始未压缩内容由大小相同的记录组成,也无法并行读取压缩文件。您必须使用关键部分串行化I/O,这将从根本上失去并行处理的好处。在单个线程中尽可能多地读取文件,然后并行处理所读取的内容,然后重复,直到EOF。
@HWI-ST298:420:B08APABXX:3:1101:1244:2212 1:N:0:TCATTC
GGCAAGGCACTTACTTTACAGCTAAAGAAGTGCAGC
+
@@@FDFFDFHCFDACGHC<<CCFEHHFCCFCEE:C?
#include <iostream>
#include <string>
#include <cstdlib>
#include <gzstream.h>
#include <omp.h>
using namespace std;

string reverseStrand (string seq);

int main (int argc, char ** argv) {
    const char* gzFqFile;
    unsigned int nReads;

    if (argc == 3) {
        gzFqFile = argv[1];
        nReads   = atoi(argv[2]); }
    else {
        printf("\n%s <*.fq.gz> <number_of_reads>\n", argv[0]);
        return 1; }

    igzstream gz(gzFqFile);
    string li, bp36, strand, revBp36;
    unsigned int i;
    #pragma omp parallel shared(gz) private(i,li,bp36,strand,revBp36)
    {
        #pragma omp for schedule(dynamic)
        for(i = 0;i < nReads;++i) {
            li      = "";
            bp36    = "";
            strand  = "";
            revBp36 = "";
            getline(gz,li,'\n');
            getline(gz,li,'\n');
            bp36 = li;
            getline(gz,li,'\n');
            strand = li;
            getline(gz,li,'\n');
            if(strand.compare("-") == 0) {
                revBp36 = reverseStrand(bp36);
            }
            cout << bp36 << " " << strand << " " << revBp36 << "\n";
        }
    }
    gz.close();
}