2.7.2.6 reduction
Это предложение выполняет сокращение в скалярных переменных, которые появляются в пределах список переменныхс оператором op. Синтаксис reduction предложение следующим образом:
reduction(op:variable-list)
Снижение обычно задается для выписки с одной из следующих форм:
x = x op expr
x binop= expr
x = expr op x (except for subtraction)
x++
++x
x--
--x
Здесь:
x
Одной из переменных, определенных в сокращения list.список переменных
Разделенный запятыми список скалярных переменных сокращения.expr
Выражение со скалярным типом, который не ссылается на x.op
Перегруженный оператор, но не одно +, -, *, &, ^, |&& - или - ||.binop
Перегруженный оператор, но не одно +, -, *, &, ^ или |.
Ниже приведен пример reduction предложение:
#pragma omp parallel for reduction(+: a, y) reduction(||: am)
for (i=0; i<n; i++) {
a += b[i];
y = sum(y, c[i]);
am = am || b[i] == c[i];
}
Как показано в примере оператор может быть скрыт в вызова функции. Пользователь должен соблюдать осторожность, оператор, определенные в reduction предложение соответствует операции приведения.
Хотя правый операнд || оператор не имеет побочных эффектов в этом примере разрешены, но они должны использоваться с осторожностью. В этом контексте побочный эффект, который гарантированно происходит во время последовательного выполнения цикла может возникнуть при выполнении параллельного выполнения. Это различие может произойти, так как порядок выполнения итераций не определен.
Оператор используется, чтобы задать начальное значение для всех закрытых переменных, используемых компилятором для уменьшения и указать оператор завершения. Определение оператора явно разрешает выписка уменьшить, чтобы быть вне лексической области памяти конструирования. Любое количество reduction предложения могут быть указаны в директиве, но переменная может появиться в максимум одно reduction предложение для директивы.
Закрытая копия каждой переменной в список переменных создает, по одному для каждого потока, если private предложение. Закрытая копия инициализируется в соответствии с оператором (см. следующую таблицу).
В конце области, для которой reduction было указано предложение, исходный объект обновляется, отражая результат объединения свое исходное значение со значением final каждой из закрытых копий с помощью указанного оператора. Операторы все уменьшить ассоциативны (за исключением вычитания), и компилятор может свободно реассоциировать вычисление конечного значения. Результаты вычитания (частично уменьшить добавляются для формирования конечного значения.)
Значение исходного объекта будет непредвиденным при достижении первый поток, содержащий предложения и остается так до тех пор, пока вычисление уменьшения не будет полностью готово. Обычно в конце конструкции вычисление будет завершено; однако, если reduction при создании в которой используется предложение nowait также применяет значение исходного объекта остается непредвиденными до тех пор, пока не будет выполняться синхронизация барьера, чтобы убедиться, что все потоки были завершены reduction предложение.
В следующей таблице перечислены операторы, которые допустимы и их канонические значения инициализации. Фактическое значение инициализации будет согласовано с типом данных переменной сокращения.
Оператор |
Инициализация |
---|---|
+ |
0 |
* |
1 |
- |
0 |
& |
~0 |
| |
0 |
^ |
0 |
&& |
1 |
|| |
0 |
Ограничения reduction предложение следующим образом:
Тип переменных в reduction предложение должно быть допустимым для оператора сократить за исключением того, что типы и ссылочные типы указателей никогда не разрешены.
Переменная, определенная в reduction предложение не должно иметь Const- qualified.
Переменные, которые являются закрытыми в параллельной области или появляется в reduction предложение a Параллельно директиву нельзя указать в a reduction предложение on рабочий-совместно с помощью директивы, привязывается к параллельной конструкции.
#pragma omp parallel private(y) { /* ERROR - private variable y cannot be specified in a reduction clause */ #pragma omp for reduction(+: y) for (i=0; i<n; i++) y += b[i]; } /* ERROR - variable x cannot be specified in both a shared and a reduction clause */ #pragma omp parallel for shared(x) reduction(+: x)