OpenMP nested l oop пропускает некоторые комбинации - PullRequest
0 голосов
/ 09 мая 2020

Я создаю параллельную программу сопоставления строк с использованием OpenMP. Вот код, соответствующий двухсимвольной строке.

void compare2(char *str) //str = 2 character string pass from main(). (for e.g. "aa")
{
    char str1[2];
    int flag = 0;

    #pragma omp parallel for collapse(2)
    for(int i=0; i<strlen(alphabet); i++)
    {
        for(int j=0; j<strlen(alphabet); j++)
        {
            if(flag)
            {
                continue;
            }
            str1[0] = alphabet[i];
            str1[1] = alphabet[j];
            str1[2] = '\0';
            printf("%s\n", str1);

            if(strcmp(str1, str) == 0)
            {
                printf("Match found %d!\n", omp_get_thread_num());
                flag = 1;
            }
        }
    }
}

Я заметил, что некоторые из комбинаций, такие как «aa», «b c», et c. часто «пропускаются». Кроме того, я не сталкиваюсь с этой проблемой, когда указываю количество потоков как num_threads(1). Проблема возникает, когда num_threads() > 1.
Примечание - была добавлена ​​переменная flag, чтобы пропускать вывод при обнаружении совпадения.

1 Ответ

2 голосов
/ 09 мая 2020

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

Но это должно быть довольно легко решить. Лучшая практика для объявлений переменных - помещать их в самую узкую область, которая позволяет им служить своей цели. Вы используете этот массив только внутри самого внутреннего l oop вашего l oop гнезда, и вы не полагаетесь на него, чтобы сохранить его значение при итерациях, поэтому вы должны объявить его внутри этого l oop. Это будет иметь дополнительный эффект предотвращения проблем, связанных с совместным использованием c, так что это полная победа. Что-то вроде этого:

void compare2(char *str) //str = 2 character string pass from main(). (for e.g. "aa")
{
    int flag = 0;

    #pragma omp parallel for collapse(2)
    for (int i = 0; i < strlen(alphabet); i++) {
        for (int j = 0; j < strlen(alphabet) && flag == 0; j++) {
            if(flag) {
                continue;
            }

            char str1[3] = { alphabet[i], alphabet[j] };

            printf("%s\n", str1);

            if (strcmp(str1, str) == 0) {
                printf("Match found %d!\n", omp_get_thread_num());
                flag = 1;
            }
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...