OpenMP и идентификатор локального хранилища потоков с помощью icc
Это простой тестовый код:
#include <stdlib.h>
__thread int a = 0;
int main() {
#pragma omp parallel default(none)
{
a = 1;
}
return 0;
}
gcc
компилирует это без проблем с -fopenmp
, но icc (ICC) 12.0.2 20110112
с -openmp
жалуется с
test.c(7): ошибка: "a" должно быть указано в списке переменных при включении OpenMP параллельной прагмы #pragma omp параллельного по умолчанию (нет)
Я понятия не имею, какая парадигма (т.е. shared
, private
, threadprivate
) относится к этому типу переменных. Какой из них правильный?
Я получаю ожидаемое поведение при вызове функции, которая обращается к этой локальной переменной потока, но у меня возникают проблемы с доступом к ней из явного параллельного раздела.
Редактировать:
Мое лучшее решение на данный момент - вернуть указатель на переменную через функцию
static inline int * get_a() { return &a; }
1 ответ
__thread
примерно аналогично тому, что threadprivate
Директива OpenMP имеет. В значительной степени (читай, когда нет объектов C++), оба часто реализуются с использованием одного и того же базового механизма компилятора и, следовательно, совместимы, но это не всегда гарантирует работу. Конечно, реальный мир далек от идеала, и нам иногда приходится жертвовать переносимостью, чтобы все работало в рамках заданных ограничений развития.
threadprivate
это директива, а не пункт, поэтому вы должны сделать что-то вроде:
#include "header_providing_a.h"
#pragma omp threadprivate(a)
void parallel_using_a()
{
#pragma omp parallel default(none) ...
... use 'a' here
}
GCC (как минимум версия 4.7.1) лечит __thread
как неявный threadprivate
декларации, и вам не нужно ничего делать.