ПОД конспект (1184369), страница 13
Текст из файла (страница 13)
С недавнего временипарадигма программирования с передачей сообщений стала популярной. Одной из причин этого сталоувеличение числа платформ, поддерживающих модель передачи сообщений. Программы, написанные сиспользованием передачи сообщений, могут выполняться на распределенных многопроцессорныхкомплексах или системах с разделяемой памятью, сетях и даже на однопроцессорых системах. Применяяпарадигму, программист знает, что его алгоритмы должны быть в принципе переносимы на любуюплатформу, поддерживающую модель передачи сообщений.
Модель передачи сообщений популярна непотому, что достаточно проста, но потому, что она фундаментальна.Программирование в модели обработки данных – параллелизм по данным. Подробнее см. Вопросы 45,46.50. Разделение последовательных программ на параллельные нити.В системах с общей памятьюВ принципе, для распараллеливания программ можно использовать механизм порождения процессов.Однако этот механизм не очень удобен, поскольку каждый процесс функционирует в своем адресномпространстве, и основное достоинство этих систем - общая память - не может быть использован простым иестественным образом. Для распараллеливания программ используется механизм порождения нитей(threads) - легковесных процессов, для которых не создается отдельного адресного пространства, но которыена многопроцессорных системах также распределяются по процессорам.
В языке программирования Cвозможно прямое использование этого механизма для распараллеливания программ посредством вызовасоответствующих системных функций, а в компиляторах с языка FORTRAN этот механизм используетсялибо для автоматического распараллеливания, либо в режиме задания распараллеливающих директивкомпилятору (такой подход поддерживают и компиляторы с языка С).Все производители симметричных мультипроцессорных систем в той или иной мере поддерживаютстандарт POSIX Pthread и включают в программное обеспечение распараллеливающие компиляторы дляпопулярных языков программирования или предоставляют набор директив компилятору дляраспараллеливания программ. В частности, многие поставщики компьютеров SMP архитектуры (Sun, HP,SGI) в своих компиляторах предоставляют специальные директивы для распараллеливания циклов. Однакоэти наборы директив, во-первых, весьма ограничены и, во-вторых, несовместимы между собой.
В результатеэтого разработчикам приходится распараллеливать прикладные программы отдельно для каждойплатформы.51. Ограничения на распараллеливание циклов.Распараллеливание циклов возможно, если все итерации цикла независимы. Тело цикла не должнысодержать: операторов перехода операторов ввода-выводаИндексные выражения не должны иметь индекс в индексе А(В(С))+ см.
вопрос 6452. Синхронизация параллельных процессов. Барьеры.Барьеры – весьма своеобразное средство синхронизации. Идея его в том, чтобы в определенной точкеожидания собралось заданное число потоков управления. Только после этого они смогут продолжитьвыполнение. (Поговорка "семеро одного не ждут" к барьерам не применима.)29Барьеры полезны для организации коллективных распределенных вычислений в многопроцессорнойконфигурации, когда каждый участник (поток управления) выполняет часть работы, а в точке сборачастичные результаты объединяются в общий итог.Функции, ассоциированные с барьерами, подразделяются на следующие группы.инициализация и разрушение барьеров: pthread_barrier_init(), pthread_barrier_destroy()#include <pthread.h>int pthread_barrier_init (pthread_barrier_t *restrict barrier,const pthread_barrierattr_t*restrict attr,unsigned count);int pthread_barrier_destroy (pthread_barrier_t *barrier);синхронизация на барьере: pthread_barrier_wait() (см.
листинг 2.37);#include <pthread.h>int pthread_barrier_wait (pthread_barrier_t *barrier);инициализация и разрушение атрибутных объектов барьеров: pthread_barrierattr_init(),pthread_barrierattr_destroy() (см. листинг 2.38);#include <pthread.h>int pthread_barrierattr_init (pthread_barrierattr_t *attr);int pthread_barrierattr_destroy (pthread_barrierattr_t *attr);опрос и установка атрибутов барьеров в атрибутных объектах: pthread_barrierattr_getpshared(),pthread_barrierattr_setpshared() (см. листинг 2.39).#include <pthread.h>int pthread_barrierattr_getpshared(const pthread_barrierattr_t*restrict attr,int *restrict pshared);int pthread_barrierattr_setpshared(pthread_barrierattr_t *attr,int pshared);Обратим внимание на аргумент count в функции инициализации барьера pthread_barrier_init().
Он задаетколичество синхронизируемых потоков управления. Столько потоков должны вызвать функциюpthread_barrier_wait(), прежде чем каждый из них сможет успешно завершить вызов и продолжитьвыполнение. (Разумеется, значение count должно быть положительным.)Когда к функции pthread_barrier_wait() обратилось требуемое число потоков управления, одному из них(стандарт POSIX-2001 не специфицирует, какому именно) в качестве результата возвращается именованнаяконстанта PTHREAD_BARRIER_SERIAL_THREAD, а всем другим выдаются нули.
После этого барьервозвращается в начальное (инициализированное) состояние, а выделенный поток может выполнитьсоответствующие объединительные действия.if ((status = pthread_barrier_wait(&barrier)) ==30/*/*/*/*PTHREAD_BARRIER_SERIAL_THREAD) {Выделенные (обычно – объединительные) */действия.*/Выполняются каким-то одним потоком */управления */} else {/* Эта часть выполняется всеми *//* прочими потоками *//* управления */if (status != 0) {/* Обработка ошибочной ситуации */} else {/* Нормальное "невыделенное" *//* завершение ожидания *//* на барьере */}}/* Повторная синхронизация – *//* ожидание завершения выделенных действий */status = pthread_barrier_wait (&barrier);/* Продолжение параллельной работы */.
. .Отметим, что для барьеров отсутствует вариант синхронизации с контролем времени ожидания. Это вполнепонятно, поскольку в случае срабатывания контроля барьер окажется в неработоспособном состоянии(требуемое число потоков, скорее всего, уже не соберется). По той же причине функцияpthread_barrier_wait() не является точкой терминирования – "оставшиеся в живых" не переживут потеритоварища...53.
Критические секции. Двоичные и общие семафоры.Процессы для своей работы могут использовать логические и физические ресурсы вычислительнойсистемы и ее окружения, причем ресурсы могут быть: поделены между процессами и закрепленыпостоянно (на все время работы процесса) или использованы всеми или некоторыми процессами поочереди. Некоторые ресурсы могут быть общими и допускать параллельное обслуживание процессов.Ресурс, который допускает обслуживание только одного процесса в текущее время, называетсякритическим ресурсом.Участки программы процесса, в которых происходит обращение к критическим ресурсам,называются критическими участками. Такие участки должны быть выполнены в режиме "взаимногоисключения", т.е.
в каждый момент времени не более чем один процесс может быть занят выполнениемсвоего, критического относительно некоторого ресурса, участка. Проблема критического участка программирование работы критических участков в режиме взаимного исключения решается с помощьюсемафоров. Общий семафор - это целочисленная переменная, над которой разрешены только двенеделимые операции P и V.
Аргументом у этих операций является семафор. Определять семантику этихопераций можно только для семафоров - положительных чисел, или включать и отрицательный диапазон.Операции могут быть определены так:P(S) - декремент и анализ семафораS := S-1IF (S < 0) THEN <блокировка текущего процесса>ENDIFV(S) - инкремент семафораS := S+1IF S <= 0 THEN <запустить блокированный процесс>ENDIFP и V операции неделимы: в каждый момент только один процесс может выполнять Р или Vоперацию над данным семафором.Если семафор используется как счетчик ресурсов, то:S >= 1 - есть некоторое количество (S) доступных ресурсов,S = 0 - нет доступного ресурса,31S < 0 - один или несколько (S) процессов находятся в очереди к ресурсу.Вводится, также, операция инициализации семафора (присвоение начального значения).Общий семафор - избыточный, т.к.
его можно реализовать через двоичные семафоры, которыепринимают только два значения 0,1.Семафоры позволяют:- синхронизировать работу процессов,- управлять распределением ресурсом (использованием положительного диапазона значенийсемафора как счетчика ресурсов) ,- организовывать очередь блокированных процессов (отрицательные значения семафора показываютчисло блокированных процессов).В системах программирования вводится специальный тип данных, определяющий структурусемафора, например, SEMAPHOR,SIGNAL,GETA.Использование семафоровbegin integer S; S:=1;parbegintask1: begindo while (true)P(S);<критический участок 1>;V(S);<обычный участок>;enddoend;task2: begindo while (true)P(S);<критический участок 2>;V(S);<обычный участок>;enddoendparendend54. Упорядоченные секции.