Идентификатор 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 parallel #pragma omp parallel default (нет)

Я понятия не имею, какая парадигма (например, shared, private, threadprivate) применима к этому типу переменных. Какой из них лучше использовать?

Я получаю ожидаемое поведение при вызове функции, которая обращается к этой локальной переменной потока, но у меня проблемы с доступом к ней из явного параллельного раздела.

Изменить:

На данный момент мое лучшее решение - вернуть указатель на переменную через функцию

static inline int * get_a() { return &a; }

person Sergey L.    schedule 14.11.2013    source источник
comment
Смешение разных моделей резьбы, вероятно, не такая уж и хорошая идея. Семантически threadprivate, вероятно, наиболее близок. Поскольку __thread является расширением компилятора, вы, вероятно, не найдете много документации, которая связывает это и OpenMP.   -  person Jens Gustedt    schedule 14.11.2013
comment
Какой компилятор вы используете? GCC не должен просить вас предоставить a явный класс совместного использования данных, даже если указан default(none).   -  person Hristo Iliev    schedule 14.11.2013
comment
@HristoIliev Я использую icc 12.0.2. И вы правы, что это похоже на проблему с icc. gcc принимает это.   -  person Sergey L.    schedule 15.11.2013
comment
Попробуйте добавить #pragma omp threadprivate(a) в следующую строку после объявления a. Это немного тавтология, поскольку в значительной степени оба делают одно и то же (за некоторыми исключительными случаями, касающимися объектов C ++).   -  person Hristo Iliev    schedule 15.11.2013
comment
@HristoIliev Это тот самый! Избавление от спецификатора __thread и установка вместо него #pragma omp threadprivate даже делает мой код совместимым с Mach-O, поскольку __thread не поддерживается в исполняемых файлах Mach-O. Если вы опубликуете это как ответ, я с радостью отдаю вам должное.   -  person Sergey L.    schedule 15.11.2013
comment
Кстати, я никогда не видел, как ICC реализует TLS в OS X, но способ GCC - ужасная эмуляция, которая очень медленная.   -  person Hristo Iliev    schedule 15.11.2013


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

person Hristo Iliev    schedule 15.11.2013
comment
Забавно: для gcc в Linux __thread и threadprivate являются синонимами и используют FS сегментный регистр на x86. В OS X (Mach-O) threadprivate заставляет gcc использовать некоторую эмуляцию под названием ___emutls_get_address. Для icc наличие __thread (не имеет отношения к threadprivate) в Linux x86 приводит к тому же поведению, что и gcc: использование регистра сегмента FS. В отсутствие __thread, но с threadprivate icc запускается с довольно сложной эмуляцией как в Linux, так и в OS X. - person Sergey L.; 15.11.2013
comment
Передача -openmp-threadprivate=compat в icc заставляет его обрабатывать threadprivate так же, как __thread в совместимых ОС / архитектурах. - person Sergey L.; 15.11.2013
comment
@SergeyL. Улучшилась ли ситуация (медленная) threadprivate с MacOS? Что лучше с GCC, ICC или Clang? Я никогда не использовал OpoenMP с MacOS (и в этом отношении я никогда ничего не компилировал с macOS), но мне просто любопытно. threadprivate эмулируется с помощью ICC в Linux? Если да, то почему? В MacOS есть ли какие-то ограничения Mach-O с TLS? - person Z boson; 14.01.2017
comment
@SergeyL. Кажется, Clang предлагает варианты изменения модели TLS -ftls-model. Также есть -femulated-tls. Это интересно. Интересно, есть ли в GCC что-то подобное. Похоже, на threadprivate нельзя положиться, если он будет хорошо реализован с разными ОС и компиляторами. - person Z boson; 14.01.2017
comment
@Zboson, возможно, разные модели TLS Clang соответствуют различным реализациям TLS в среде выполнения Intel OpenMP, которую он использует по умолчанию. Компиляторы Intel имеют такую ​​же возможность. - person Hristo Iliev; 14.01.2017
comment
@HristoIliev, Clang по умолчанию использует среду выполнения Intel OpenMP? Это даже с открытым исходным кодом или в свободном доступе? Я думал, что Clang использует gomp или собственную среду выполнения OpenMP? - person Z boson; 19.01.2017
comment
@Zboson, Intel OpenMP Runtime была открыта довольно давно и является основой OpenMP. поддержка в Clang. Приятно видеть, что люди из IBM тоже работают над этим. - person Hristo Iliev; 19.01.2017