2013-11-14 2 views
2

Это простой тестовый код:OpenMP и Thread Local идентификатор хранилища с 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): error: "a" must be specified in a variable list at enclosing OpenMP parallel pragma #pragma omp parallel default(none)

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

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

Edit:

Мой лучшее решение до сих пор вернуть указатель на переменную с помощью функции

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

Смешивание различных моделей нитей, вероятно, не такая хорошая идея. Семантически 'threadprivate', вероятно, самый близкий. Поскольку '__thread' является расширением для компилятора, вы, вероятно, не найдете много документации, которая связывает это и OpenMP. –

+0

Какой компилятор вы используете? GCC не должен просить вас предоставить 'a' явный класс совместного использования данных, даже если указан параметр' default (none) '. –

+0

@HristoIliev Я использую 'icc' 12.0.2. И вы правы, что это, похоже, проблема с 'icc'. 'gcc' принимает это. –

ответ

3

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

+0

Смешная вещь: для 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. –

+0

Передача '-openmp-threadprivate = compat' в icc заставляет его обрабатывать' threadprivate' так же, как '__thread' на совместимых ОС/архитектурах. –

+0

@SergeyL. Улучшена ли ситуация (медленная) «threadprivate» с MacOS? Теперь лучше с GCC, ICC или Clang? Я никогда не использовал OpoenMP с MacOS (и в этом отношении я никогда не компилировал ничего с macOS), но мне просто интересно. Является ли 'threadprivate' эмулированным с ICC на Linux? Если да, то почему? На MacOS есть какое-то ограничение Mach-O с TLS? –

Смежные вопросы