C - 无效分支 to/from OpenMP 结构化块

C - invalid branch to/from OpenMP structured block

我在 c 中有一个代码可以计算特定单词的出现次数,但我想用 openmp 来实现。

哪个单词是 char 并且在 main() 中定义

当我尝试编译它时出现以下错误:

In function ‘wordCount’: error: invalid branch to/from OpenMP structured block

我试图搜索同样的错误,但我无法修复它,我是 openmp 的新手,尤其是 c。

完整代码如下:

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <sys/time.h>
    #include <omp.h>
    
    struct timeval t1, t2;
    
    void execTime(){
      double t_total = (t2.tv_sec - t1.tv_sec) + ((t2.tv_usec - t1.tv_usec)/1000000.0);
      printf("\n");
      printf("\n");
      printf("Total Time = %f\n", t_total);
      printf("\n");
    }
    
    int wordCount(char* file_path, char* word){
        FILE *fp;
        int count = 0;
        int ch, len;
    
        if(NULL==(fp=fopen(file_path, "r")))
            return -1;
        len = strlen(word);
        for(;;){
            int i;
            if(EOF==(ch=fgetc(fp))) break;
            if((char)ch != *word) continue;
            
           omp_set_num_threads(4);
    
           #pragma omp parallel for  
            for(i=1;i < len;++i){
                if(EOF==(ch = fgetc(fp))) 
                    goto end;
                if((char)ch != word[i]){
                    fseek(fp, 1-i, SEEK_CUR);
                    goto next;
                }
            }
            ++count;
            next: ;
        }
        end:
            fclose(fp);
            return count;
    }
    
    int main()
    {
        char word1[] = "hello";
        char word2[] = "libero";
        char word3[] = "egestas";
        char word4[] = "vestibulum";
    
        int wordcount1 = 0;
        int wordcount2 = 0;
        int wordcount3 = 0;
        int wordcount4 = 0;
    
        gettimeofday(&t1, NULL);
      
        wordcount1 = wordCount("file.txt", word1);
        wordcount2 = wordCount("file.txt", word2);
        wordcount3 = wordCount("file.txt", word3);
        wordcount4 = wordCount("file.txt", word4);
        gettimeofday(&t2, NULL);
    
        printf("Word hello occurs %d times\n",wordcount1);
        printf("Word libero occurs %d times\n",wordcount2);
        printf("Word egestas occurs %d times\n",wordcount3);
        printf("Word vestibulum occurs %d times\n",wordcount4);
        execTime();
        return 0;
    }

您不能在 OpenMP goto 语句中使用并行语句:

   #pragma omp parallel for  
    for(i=1;i < len;++i){
        if(EOF==(ch = fgetc(fp))) 
            goto end; // <-- the problem
        if((char)ch != word[i]){
            fseek(fp, 1-i, SEEK_CUR);
            goto next; // <-- the problem
        }
    }

同样适用于break语句,从OpenMP 5.1标准可以读到:

final-loop-body must not contain any break statement that would cause the termination of the innermost loop.

您可以尝试查看 OpenMP cancellation point 功能:

Summary

The cancellation point construct introduces a user-defined cancellation point at which implicit or explicit tasks check if cancellation of the innermost enclosing region of the type specified has been activated. The cancellation point construct is a stand-alone directive.


但是,在您的情况下,即使 goto 不是问题,您的代码也不能像现在这样有效地并行化。例如,fgetc

Note: This function is not thread safe, because it shares a return buffer across all threads, and many other functions in this library. const char *explain_errno_fgets(int errnum, char *data, int data_size, FILE *fp);

不是线程安全的,这意味着您必须确保 mutual exclusion 对其访问,这将使您的代码基本上是顺序的。通常不建议并行读取同一个文件。