C — недопустимая ветвь в / из структурированного блока OpenMP

#c #multithreading #parallel-processing #openmp

#c #многопоточность #параллельная обработка #openmp

Вопрос:

У меня есть код на c, который подсчитывает количество вхождений определенных слов, но я хочу сделать это с помощью openmp.

Какое слово является символом и определено в main()

Когда я пытаюсь его скомпилировать, я получаю следующую ошибку:

В функции ‘WordCount’: ошибка: недопустимая ветвь в / из структурированного блока OpenMP

Я пытался найти эту же ошибку, но я не могу ее исправить, я очень новичок в 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 = %fn", 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(amp;t1, NULL);
      
        wordcount1 = wordCount("file.txt", word1);
        wordcount2 = wordCount("file.txt", word2);
        wordcount3 = wordCount("file.txt", word3);
        wordcount4 = wordCount("file.txt", word4);
        gettimeofday(amp;t2, NULL);
    
        printf("Word hello occurs %d timesn",wordcount1);
        printf("Word libero occurs %d timesn",wordcount2);
        printf("Word egestas occurs %d timesn",wordcount3);
        printf("Word vestibulum occurs %d timesn",wordcount4);
        execTime();
        return 0;
    }
 

Ответ №1:

Вы не можете иметь оператор in OpenMP goto внутри параллельного for:

    #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 не должен содержать никакого оператора break, который мог бы привести к завершению самого внутреннего цикла.

Вы можете попробовать взглянуть на функцию точки отмены OpenMP:

Краткие сведения

Конструкция точки отмены вводит определяемую пользователем точку отмены, в которой неявные или явные задачи проверяют, была ли активирована отмена самой внутренней области указанного типа. Конструкция точки отмены является автономной директивой.


Однако в вашем случае, даже если переход не был проблемой, ваш код неэффективно распараллеливается. Например, fgetc

Примечание: эта функция не является потокобезопасной, поскольку она совместно использует буфер возврата для всех потоков и многих других функций в этой библиотеке. const char *explain_errno_fgets(int errnum, char *data, int data_size, FILE *fp);

Не является потокобезопасным, что означает, что вам нужно будет обеспечить взаимное исключение при его доступе, что в любом случае сделает ваш код в основном последовательным. Обычно в любом случае не рекомендуется читать один и тот же файл параллельно.