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 декларации, и вам не нужно ничего делать.

Другие вопросы по тегам