openmp – 用于文本文件读取和使用管道的while循环

我发现openmp不支持while循环(或者至少不太喜欢它们)。 而且也不喜欢’!=’运算符。

我有这段代码。

int count = 1; #pragma omp parallel for while ( fgets(buff, BUFF_SIZE, f) != NULL ) { len = strlen(buff); int sequence_counter = segment_read(buff,len,count); if (sequence_counter == 1) { count_of_reads++; printf("\n Total No. of reads: %d \n",count_of_reads); } count++; } 

关于如何管理这个的任何线索? 我在某地读过(包括stackoverflow的另一篇文章)我可以使用管道。 那是什么 ? 以及如何实施它?

在OpenMP中实现“并行时”的一种方法是使用创建任务的while循环。 这是一般草图:

 void foo() { while( Foo* f = get_next_thing() ) { #pragma omp task firstprivate(f) bar(f); } #pragma omp taskwait } 

对于循环遍历fgets的特定情况,请注意fgets具有固有的顺序语义(它获取“下一行”),因此需要在启动任务之前调用它。 对每个任务来说,操作自己的fgets返回的数据副本也很重要,这样对fgets的调用不会覆盖前一个任务正在操作的缓冲区。

人们选择最佳答案的速度太快了。 这是我的答案。
首先,你应该将文件读入一个像fread这样的缓冲区。 这很快。 有关如何执行此操作的示例,请访问http://www.cplusplus.com/reference/cstdio/fread/

然后,您可以与OpenMP并行操作缓冲区。 我已经为你实现了大部分内容。 以下是代码。 你没有提供segment_read函数,所以我创建了一个虚拟函数。 我使用了C ++中的一些函数,比如std :: vector和std :: sort,但是你可以在纯C中做更多的工作。

编辑:我编辑了这段代码,并且能够删除排序和关键部分。

我用g++ foo.cpp -o foo -fopenmp -O3编译了g++ foo.cpp -o foo -fopenmp -O3

 #include  #include  #include  using namespace std; int segment_read(char *buff, const int len, const int count) { return 1; } void foo(char* buffer, size_t size) { int count_of_reads = 0; int count = 1; std::vector *posa; int nthreads; #pragma omp parallel { nthreads = omp_get_num_threads(); const int ithread = omp_get_thread_num(); #pragma omp single { posa = new vector[nthreads]; posa[0].push_back(0); } //get the number of lines and end of line position #pragma omp for reduction(+: count) for(int i=0; i 

首先,即使它非常接近,但openmp并不能让你的代码平行。 它适用for因为它具有可以理解的下限和上限。 Openmp使用这些边界来划分不同线程之间的工作。

while循环没有这样的事情。

其次,您如何期望并行化您的任务? 您正在从一个文件中读取,其中顺序访问可能会比并行访问提供更好的性能。 您可以并行化segment_read (基于其实现)。

或者,您可能希望将文件读取与处理重叠。 为此,您需要使用更多低级函数,例如Unix的openread函数。 然后,执行异步读取,这意味着您发送读取请求,处理最后一个读取块,然后等待读取请求完成。 例如,搜索“linux asynchronous io”以阅读更多内容。

使用管道实际上可能对您没有多大帮助。 这将取决于我不熟悉的管道内部的许多内容。 但是,如果您有足够大的内存,您可能还需要先考虑加载整个数据,然后再进行处理。 这样,加载数据尽可能快(按顺序)完成,然后您可以并行化其处理。