У меня очень мало опыта использования OpenMP. Я пытаюсь запустить цикл for параллельно, который вызывает другую внешнюю функцию. Я компилирую программу с MinGW, поэтому, к сожалению, у меня нет какой-либо ошибки, которая указывает, что я делаю неправильно, программа просто не запускается, когда я пытаюсь добавить параллель для внешнего цикла. findCombinations() - довольно большая функция, которая вызывает другую функцию. Мне интересно, можно ли использовать параллельный цикл в этом сценарии? и если да, то есть ли что-нибудь, что я делаю вопиюще неправильно?OpenMP - вызов внешних функций в параллельном для цикла
#pragma omp parallel for
for(int j = 0; j < n[i].count; j++) {
int length = 0;
while(n[i].neighbourhoods[j][length].index != -1) length++;
bool used[length];
memset(used, false, sizeof(used));
findCombinations(&b, n[i].neighbourhoods[j], length, 0, 0, used, n[i].col);
free(n[i].neighbourhoods[j]);
}
Вот findCombinations()
int findCombinations(struct blocks *b, struct element neighbourhood[], int neighbourhoodSize, int start, int currLen, bool used[], int col) {
if (currLen == blocksize) {
b->blocks[b->count].elements = malloc((blocksize+1) * sizeof(struct element));
b->blocks[b->count].col = col;
int blockCount = 0;
for (int i = 0; i < neighbourhoodSize; i++) {
if (used[i] == true) {
b->blocks[b->count].elements[blockCount++] = neighbourhood[i];
}
}
b->blocks[b->count].elements[blocksize] = neighbourhood[neighbourhoodSize]; //ensures the last item is -1
b->blocks[b->count].signature = getSignature(b->blocks[b->count].elements);
return 1;
}
if (start == neighbourhoodSize) {
return 0;
}
int new = 0;
used[start] = true;
b->count += findCombinations(b, neighbourhood, neighbourhoodSize, start + 1, currLen + 1, used, col);
used[start] = false;
b->count += findCombinations(b, neighbourhood, neighbourhoodSize, start + 1, currLen, used, col);
return new;
}
Я думаю, что проблема может быть, что findCombinations() изменяет указатель я посылаю к нему, * б, что может вызвать состояние гонки. Моя проблема в том, что я не уверен, как обойти это.
Просьба привести полный пример, чтобы мы могли лучше вам помочь. Сначала подумайте - убедитесь, что вы включили поддержку OpenMP в своем компиляторе. Например, если вы используете GCC для Linux, вам нужно включить '-fopenmp' в строку компиляции. – David
Извините - добавлена функция, вызываемая им сейчас. Я использую окна, и я установил MinGW для компиляции с gcc, просто компилируя через командную строку с -fopenmp –
Конечно, у вас есть проблема со всеми вашими потоками, работающими над одним и тем же указателем 'b'. Это становится еще хуже, осознавая, что 'findCombinations()' является рекурсивной функцией. Вероятно, вы, вероятно, сможете это исправить, используя некоторые «критические» разделы здесь и там, но я сомневаюсь, что окончательная скорость будет стоить того. Если вам нужна производительность, вам, вероятно, лучше придется серьезно пересмотреть ваш алгоритм. – Gilles