Поможем написать учебную работу
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
Преимущества и недостатки. 1) мультипроцессоры с использованием единой общей памяти. Достоинства - обеспечивается однородный доступ к памяти - является основой для построения векторных параллельных процессоров, симметричных мультипроцессоров Недостатки - необходимость синхронизации взаимодействия одновременно выполняемых потоков команд - доступ с разных процессоров к общим данным данным, как следствие, обеспечение однозначности содержимого разных кэшей. |
Основы технологии Open MP. Описание параллельных областей. Для определения параллельных областей программы используется директива Parallel,основная директива OpenMP Когда основной поток выполнения достигает директивы parallel, создается набор потоков; входной поток является основным потоком этого набора (master thread) и имеет номер 0. Код области дублируется или разделяется между потоками для параллельного выполнения. В конце области обеспечивается синхронизация потоков выполняется ожидание завершения вычислений всех потоков; далее все потоки завершаются дальнейшие вычисления продолжает выполнять только основной поток Формат директивы parallel |
Реализация стандарта Open MP памятью в настоящее время является технология OpenMP. |
Положительные и отрицательные стороны технологии Open MP Положительные стороны: * поддержка в наиболее *организация взаимодействия потоков через общие переменные приводит к трудно обнаруживаемым ошибкам |
Схема FORK/JOIN Используется для поддержки параллелизма. Операция FORK порождение дополнительных нитей нитью-мастером при входе в параллельную область. Каждая нить получает уникальный номер. Нить-мастер всегда имеет номер 0. JOIN: При выходе из параллельной области основная нить дожидается завершения остальных нитей, и дальнейшее выполнение программы продолжает только она. |
Распределение вычислений между потоками в OpenMP. Программирование на низком уровне. Распределение вычислений между потоками Программирование на низком уровне предполагает распределение работы с помощью функций omp_get_thread_num() и omp_get_num_threads(), возвращающих номер нити и общее количество порожденных нитей соответственно. Например, если написать фрагмент вида: if (omp_get_thread_num() == 3) {<индивидуальный код для нити с номером 3> } else {<код для всех остальных нитей> } то часть программы между операторами if...else будет выполнена только нитью с номером 3, а часть после else всеми остальными. Как и прежде, исходный код остается одинаковым для всех нитей. Однако реальная передача управления в нем будет идти для разных нитей по-разному, поскольку функция omp_get_thread_num() возвратит значение 3 только для нити с номером 3. #include <omp.h> void main () {int nthreads, tid; // Создание параллельной области #pragma omp parallel private(nthreads, tid) {// печать номера потока tid = omp_get_thread_num(); printf("Hello World from thread = %d\n", tid); // Печать количества потоков только master if (tid == 0) { nthreads = omp_get_num_threads(); printf("Number of threads = %d\n", nthreads); } } // Завершение параллельной области } |
Распределение вычислений между потоками в OpenMP. Директива for. Операция редукции. Примеры. Если в параллельной секции встретился оператор цикла, то согласно общему правилу он будет выполнен всеми нитями, т. е. каждая нить выполнит все итерации данного цикла. Для распределения итераций цикла между нитями нужно использовать директиву for: #pragma omp for <for-цикл> Данная директива относится к идущему следом за ней оператору for. Переменная цикла по умолчанию полагается локальной. Параллельная область уже должна быть активна, иначе директива игнорируется. #pragma omp for[clause …] for loop { } Опция SCHEDULE определяет конкретный способ распределения итераций данного цикла по нитям. STATIC [,m] блочно-циклическое распределение итераций. Первый блок из m итераций выполняет первая нить, второй блок вторая и т. д. до последней нити, затем распределение снова начинается с первой нити. DYNAMIC [,m] динамическое распределение итераций с фиксированным размером блока. Сначала все нити получают порции из m итераций, а затем каждая нить, заканчивающая свою работу, получает следующую порцию, содержащую также m итераций. GUIDED [,m] динамическое распределение итераций блоками умень-шающегося размера. Сначала размер выделяемых блоков берется достаточно большим, а в процессе работы программы он все время уменьшается. Минимальный размер блока итераций равен m. RUNTIME способ распределения итераций цикла выбирается во время работы программы в зависимости от значения переменной OMP_SCHEDULE.Распределение вычислений между потоками n Выбранный способ распределения итераций указывается в скобках после опции SCHEDULE, например: #pragma omp for schedule(dynamic, 10) #include <omp.h> // пример # define CHUNK 100 # define NMAX 1000 void main(){ int i, n, chunk; float a[NMAX], b[NMAX], c[NMAX]; // Инициализация for (i=0; i<NMAX; i++) a[i] = b[i]=i*1.0; n=NMAX; chunk=CHUNK; #pragma omp parallel shared(a,b,c,n,chunk) private(i) { #pragma omp for schedule(dynamic,chunk) nowait for(i=0; i<n; i++) c[i] = a[i] + b[i] } } |
Синхронизация работы нитей. Целый набор директив в ОрепМР предназначен для синхронизации работы нитей. Самый распространенный и простой способ синхронизации это барьер. Он оформляется с помощью директивы #pragma omp barrier Все нити, дойдя до этой директивы, останавливаются и ждут пока все оставшиеся нити не дойдут до этой точки программы, после чего все нити продолжают работать дальше. Директива MASTER выделяет участок кода, который будет выполнен только нитью-мастером. Остальные нити просто пропускают данный участок и продолжают работу с оператора, расположенного следом за блоком. #pragma omp master structured_block С помощью директив #pragma omp critical [ name ] structured_block оформляется критическая секция программы. В каждый момент времени в критической секции может находиться не более одной нити. #include <omp.h> main() { int x; x = 0; #pragma omp parallel shared(x) { #pragma omp critical x = x + 1; } /* end of parallel section */} Директива atomic определяет переменную, доступ к которой (чтение/запись) должна быть выполнена как неделимая операция #pragma omp atomic SUM = SUM + Expr; Данная директива относится только к идущему непосредственно за ней оператору. В данном примере ATOMIC гарантирует корректную работу с общей переменной SUM Поскольку в современных параллельных вычислительных системах может использоваться сложная структура и иерархия памяти, пользователь должен иметь гарантии того, что в необходимые ему моменты времени каждая нить будет видеть единый согласованный образ памяти. Для этих целей предназначена директива #pragma omp flush (list) Директива ordered указывает фрагмент кода параллельного цикла, который должен выполняться точно в таком же порядке, как и при последовательном выполнении #pragma omp ordered structured_block • В каждый момент времени в блоке ordered может находиться только один поток • На одной итерации цикла может быть только одна директива ordered и эта директива может выполниться только однократно • Цикл, в котором имеется директива ordered, должен иметь параметр ordered |
Директивы sections, single, master, atomic, flush, ordered. Примеры. Параллелизм на уровне независимых фрагментов оформляется в ОреnМР с помощью директивы SECTIONS и какого-то числа директив SECTION, расположенных внутри этого блока. #pragma omp sections { #pragma omp section {<фрагмент 1> } #pragma omp section {<фрагмент 2> } #pragma omp section {<фрагмент 3> } } Формат директивы sections #pragma omp sections [clause ...] { #pragma omp section structured_block #pragma omp section structured_block} Директива MASTER выделяет участок кода, который будет выполнен только нитью-мастером. Остальные нити просто пропускают данный участок и продолжают работу с оператора, расположенного следом за блоком MASTER. Неявной синхронизации данная директива не предполагает. #pragma omp master structured_block Если в параллельной секции какой-либо участок кода должен быть выполнен лишь один раз, то его нужно заключить в директиву SINGLE. Подобная необходимость часто возникает при работе с общими переменными. Указанный участок будет выполнен только одной нитью. Если не указан параметр NOWAIT, то все остальные потоки ожидают завершения выполнения фрагмента. Формат директивы single #pragma omp single [clause …] structured_block Директива atomic определяет переменную, доступ к которой (чтение/запись) должна быть выполнена как неделимая операция #pragma omp atomic SUM = SUM + Expr; Данная директива относится только к идущему непосредственно за ней оператору. В данном примере ATOMIC гарантирует корректную работу с общей переменной SUM Поскольку в современных параллельных вычислительных системах может использоваться сложная структура и иерархия памяти, пользователь должен иметь гарантии того, что в необходимые ему моменты времени каждая нить будет видеть единый согласованный образ памяти. Для этих целей предназначена директива #pragma omp flush (list) Директива ordered указывает фрагмент кода параллельного цикла, который должен выполняться точно в таком же порядке, как и при последовательном выполнении #pragma omp ordered structured_block • В каждый момент времени в блоке ordered может находиться только один поток • На одной итерации цикла может быть только одна директива ordered и эта директива может выполниться только однократно • Цикл, в котором имеется директива ordered, должен иметь параметр ordered |