#variables #openmp
#переменные #openmp
Вопрос:
Я пытаюсь адаптировать обычный код к параллельному. Когда я создаю параллельный цикл for, внутри которого объявлены некоторые переменные, являются ли эти переменные частными или общими?
Должен ли я определять каждый из них как закрытый, когда я определяю pragma?
Кстати, еще один последний вопрос. Я тоже могу использовать for-pragma с начальным параметром итератора, верно? Нравится for(iter=xlist.begin() ; ... )
Я использую последнюю версию codeblocks и mingw.
Ответ №1:
Все, что объявлено внутри параллельной области (будь то цикл или нет), является закрытым, за исключениями, перечисленными ниже в комментарии @ejd. Вы не можете указать это как частное в #pragma
строке, поскольку переменная еще не существует.
Так, например, в приведенном ниже примере, даже с default(none)
нам не нужно указывать общий доступ к tid
, даже если бы вы могли; это внутри параллельной секции, поэтому оно является частным для каждого потока. (Также обратите внимание, что на самом деле вам не нужно указывать i как private, поскольку индекс цикла omp for обязательно является private.)
$ more foo.c
#include <stdio.h>
#include <omp.h>
int main(int argc, char *argv[]) {
int i;
#pragma omp parallel for default(none) private(i)
for(i=0;i<10;i ){
int tid = omp_get_thread_num();
printf("Thread %d gets iteration %dn", tid, i);
}
return 0;
}
gpc-f103n084-$ !g
gcc -o foo foo.c -fopenmp
$ ./foo
Thread 1 gets iteration 2
Thread 1 gets iteration 3
Thread 3 gets iteration 6
Thread 3 gets iteration 7
Thread 0 gets iteration 0
Thread 0 gets iteration 1
Thread 4 gets iteration 8
Thread 4 gets iteration 9
Thread 2 gets iteration 4
Thread 2 gets iteration 5
Комментарии:
1. Да, но я подумал, может быть, мне следует объявить их перед определением прагмы и использовать их после. Я подозревал о возможном незаконном использовании, поскольку никогда не видел такого примера в руководствах, которые я читал.
2. Нет, на самом деле, их определение внутри параллельной секции хорошо, это делает вещи намного понятнее. Все, что является локальным для определенного индекса цикла, обязательно является чем-то, что можно с пользой сделать закрытым для соответствующего потока.
3. большое спасибо, это действительно было отличной помощью. большое тебе спасибо
4. Кстати, последний вопрос. Я тоже могу использовать for pragma с начальным параметром итератора, верно? например, для(iter=xlist.begin() ; … )
5. Джонатан — ваше утверждение «все, что объявлено внутри параллельной секции (будь то цикл или нет), является закрытым» не совсем точно. В спецификации OpenMP четко указано, что является закрытым, а что нет по умолчанию. Например, статические переменные, объявленные внутри конструкции, являются общими, как и переменные с выделенным хранилищем в куче, и (в версии V3.0) переменные с типом, определяемым const, не имеющие изменяемых элементов, являются общими. Существуют определенные правила по умолчанию для объявления этих переменных внутри конструкции или области (термин «параллельный раздел» не имеет значения в этом отношении).
Ответ №2:
Если они нужны вам только внутри блока цикла и вы хотите распараллелить цикл, оставьте их внутри блока цикла. Если вы объявите их вне параллельной конструкции и объявите их как частные, каждый поток будет иметь свою собственную копию. Так что это не имеет значения.
Комментарии:
1. Большое вам спасибо. Кстати, последний вопрос. Я тоже могу использовать for-pragma с начальным параметром итератора, верно? например, «for(iter=xlist.begin() ; … )»
2. Это зависит от спецификации OpenMP, поддерживаемой вашим компилятором. Я думаю, вы можете использовать прагму for для итераторов с OpenMP 3.0.