Цикл for
цикл for должен иметь классическую форму языка Си: for (выражение; логическая_операция; приращение) { Тело цикла } Оператор может иметь один из следующих типов: private (список) firstprivate (список) lastprivate (список) reduction (оператор: список) Ordered schedule (вид [, длина_порции ]) Nowait Операторы private, firstprivate, lastprivate и reduction рассматривались ранее. Оператор ordered определяет блок, в котором итерации цикла выполняются в последовательном режиме. Не допускается использование в конструкции for оператора ordered более одного раза. Оператор schedule определяет, как итерации цикла делятся между нитями группы. Правильность программы не должна зависеть от того, какая нить выполняет конкретную итерацию. Вид планирования может быть одним из следующих:
Примеры использования циклов: int a[10]; #pragma omp parallel private(i) { #pragma omp for schedule(static, 3) for(i=0; i<10; i++) a[i] = i+1; }
int a[10]; #pragma omp parallel private(i) { #pragma omp for schedule(dynamic, 3) for(i=0; i<10; i++) a[i] = i+1; }
int a[10]; #pragma omp parallel private(i) { #pragma omp for schedule(guided, 3) for(i=0; i<10; i++) a[i] = i+1; }
Пример: Цикл выполняет инициализацию элементов двумерного массива целых чисел. Количество потоков равно 2. Внешний цикл по переменной i объявлен параллельным, внутренний цикл по переменной j будет выполняться последовательно каждой нитью. Выполняется блочно-циклическое распределение итераций внешнего цикла по две итерации в блоке.
int a[4][4]; #pragma omp parallel private(i) { #pragma omp for schedule(static, 2) for(i=0; i<4; i++) {
{ a[i] [j]= i+1; } } } Пример:внутренний цикл по переменной j объявлен параллельным, внешний цикл переменной i будет выполняться последовательно каждой нитью. Выполняется блочно-циклическое распределение итераций внутреннего цикла по две итерации в блоке.
int a[4][4]; for(i=0; i<4; i++) {
{ #pragma omp for schedule(static,2) for(j=0; j<4; j++) { a[i][j]=i+1; } } } Оператор nowait – если не указан, то конструкция for завершится барьерной синхронизацией. Ограничения к применению for. Цикл for 1. должен быть блоком (т.е. должны использоваться фигурные скобки), 2. не должен содержать оператор break, 3. содержать только один оператор schedule, ordered, nowait, 4. Значение длина_порции должно быть одно и тоже для всех нитей в группе. Пример:Если внутри параллельной области несколько независимых циклов, можно использовать nowait, чтобы избежать барьерной синхронизации в конце директивы for. В параллельной области сначала будет выполнен первый цикл, итерации распределяются динамически и, не дожидаясь окончания первого цикла, первая свободная нить начнет выполнять второй цикл. #pragma omp parallel { #pragma omp for nowait for (i=0; i<n; i++) b[i] = (a[i] + a[i-1]) / 2.0; #pragma omp for nowait for (i=0; i<m; i++) y[i] = sqrt(z[i]); } Динамическая привязка директив должна придерживаться следующих правил: 1. Директивы for, sections, single, master и barrier динамически привязываются к внешней директиве parallel, если она, конечно, существует. Если нет параллельной области, выполняемой в данный момент, вышеуказанные директивы не имеют никакого действия. 2. Директива ordered динамически привязывается к внешней директиве for. 3. Директива atomic навязывает монопольный доступ в соответствии с директивой atomic во всех нитях, и не только в текущей группе. 4. Директива critical навязывает монопольный доступ в соответствии с директивой critical во всех нитях, и не только в текущей группе. 5. Директива никогда не может быть привязана к любой директиве вне ближайшей директивы parallel.
Динамическое вложение директив должно придерживается следующих правил:
1. Директива parallel динамически вне другой директивы parallel логически порождает новую группу, которая состоит только из текущей нити, если только вложенный параллелизм разрешен. 2. Директивы for, sections и single, которые привязаны к одной и тоже директиве parallel, не могут быть вложенными одна в другую. 3. Критическая секция не может быть вложена в другую критическую секцию с тем же именем. 4. Директива master запрещена в блоках директив for, sections и single. 5. Секция ordered запрещена в в блоке секции critical. 6. Директивы for, sections и single не допустимы в блоках critical, ordered и master. 7. Директива barrier не допустима в блоках for, ordered, sections, single, master, и critical.
|