#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);
Не является потокобезопасным, что означает, что вам нужно будет обеспечить взаимное исключение при его доступе, что в любом случае сделает ваш код в основном последовательным. Обычно в любом случае не рекомендуется читать один и тот же файл параллельно.