Передача данных с помощью директивы threadprivate

В этом же разделе внимание сфокусировано на проблеме передачи данных между параллельными потоками из одного параллельного структурного блока программы в другой, минуя промежуточный последовательный структурный блок. Для реализации такого механизма передачи данных в OpenMP имеется специальная директива threadprivate.

Директива threadprivate применяется к глобальным переменным программы, которые нужно сделать локальными переменными для каждого из параллельных потоков. Кроме того, эта директива позволяет передавать локальные данные из одного параллельного структурного блока в другой, а также сохранять локальные данные из параллельных потоков на протяжении всей программы.

В программах, написанных на языке C/C++, предложение threadprivate имеет следующий вид:

#pragma omp threadprivate(var)

var

A comma-separated list of variables that you want to make private to a thread. var must be either a global- or namespace-scoped variable or a local static variable.

Отметим, что элементами списка не могут быть ссылки или переменные, не полностью определенные. Кроме того, адреса констант также недопустимы в списке.

Все переменные, включенные в список директив threadprivate, должны быть проинициализированы до начала первого параллельного блока, и их инициализация возможна только один раз на протяжении всей программы. Кроме того, переменные, включенные в список, не могут фигурировать в других предложениях OpenMP, за исключением copyin, schedule или if. Категорически запрещено их использование в директивах private, firstprivate, lastprivate, shared и reduction.

Не допускается применение передачи значений переменных из одного параллельного структурного блока в другой в динамическом (dynamic) режиме работы параллельной программы. На всем протяжении действия директивы threadprivate должен быть установлен статический режим работы параллельной программы.

Ниже приведен пример фрагмента параллельной программы, написанной на языке C/C++ с использованием директивы OpenMP threadprivate. В этом примере для отмены динамического режима явно вызывается функция из библиотеки реального времени runtime OpenMP omp_set_dynamic с параметром 0.

#include <omp.h> int alpha [10], beta[10], i; #pragma omp threadprivate (alpha) main ( ){/*Выключение динамического режима*/ omp_set_dynamic (0); /*1-й параллельный блок */ #pragma omp parallel private (i, beta) for (i=0; i<10; i++) alpha[i] = beta[i] = i; /*2-й параллельный блок*/ #pragma omp parallel printf ("alpha[3]=%d and beta [3] =%d\n", alpha[3], beta[3]);}

Если изменить значение переменной, объявленной как threadprivate, начальное значение переменной в параллельной секции окажется непредсказуемым.

Приведем пример.

Некорректно:

int a = 5; #pragma omp threadprivate(a) int _tmain(int argc, _TCHAR* argv[]) { ... a = 10; #pragma omp parallel num_threads(2) { #pragma omp critical { printf("nThread #%d: a = %d", omp_get_thread_num(),a); } } getchar(); return 0; }

В результате выполнения этого кода один из потоков выведет значение 5, а другой выведет 10. Если убрать инициализацию переменной а до директивы threadprivate, один из потоков начнет выводить 0, а второй – по-прежнему 10. Избавиться от непредсказуемого поведения удастся лишь убрав второе присваивание. В этом случае оба потока будут выводить значение 5 (если первое присваивание все же оставить). Конечно, такие исправления изменят поведение кода.

Авторы [2] вообще от использования этой директивы советуют отказаться. В этом случае код станет намного более предсказуемым и понятным.

Корректно:

int a = 5; int _tmain(int argc, _TCHAR* argv[]) { ... a = 10; #pragma omp parallel num_threads(2) { int a = 10; #pragma omp barrier #pragma omp critical { printf("nThread #%d: a = %d", omp_get_thread_num(),a); } } getchar(); return 0; }

 








Дата добавления: 2015-02-03; просмотров: 1285;


Поиск по сайту:

При помощи поиска вы сможете найти нужную вам информацию.

Поделитесь с друзьями:

Если вам перенёс пользу информационный материал, или помог в учебе – поделитесь этим сайтом с друзьями и знакомыми.
helpiks.org - Хелпикс.Орг - 2014-2024 год. Материал сайта представляется для ознакомительного и учебного использования. | Поддержка
Генерация страницы за: 0.004 сек.