СКИПОДы конспект лекций (1127769), страница 13
Текст из файла (страница 13)
К ним, кромеперечисленных выше, можно отнести задачи решения линейных и нелинейных алгебраических уравнений инеравенств большой размерности; систем нелинейных дифференциальных уравнений; уравнений в частныхпроизводных; задач оптимизации и других задач.49. Модели программирования для систем с разделяемой, распределенной памятью.Программирование в модели общей памяти. (POSIX threads, OpenMP). Для SMP-систем существуютсравнительно эффективные средства автоматического распараллеливания.
Подробнее см. Вопросы .Программирование в модели распределенной памяти. Программирование в рамках модели передачисообщений (MPI, PVM, BSPlib).Эта модель схожа с парадигмой последовательного программирования. Программист имел упрощеннуюточку зрения на целевую машину, которая имеет единственный процессор и адресуется к определенномуобъему памяти.
Поэтому он писал единственную программу, чтобы выполнять ее на этом процессоре. В28сущности, парадигма может быть обеспечена разными путями, возможно, в системе разделения времени,где другие процессы разделяют процессор и память, но программисту нет необходимости вдаваться такиедетали реализации, если он уверен, что программа или разработанный алгоритм в принципе могут бытьперенесены на любую логическую архитектуру -- это сущность парадигмы.Парадигма передачи сообщений является развитием этой идеи применительно к целям параллельногопрограммирования.
Некоторые положения последовательной парадигмы сохраняются. Так, программистпредставляет несколько процессоров, каждый со своим адресным пространством, и составляет программу,чтобы запустить ее на каждом процессоре. Параллельное программирование по определению требуетвзаимодействия между процессорами для решения задачи, используя некоторую связь.
Основное положениепарадигмы передачи сообщений - процессы общаются путем передачи друг другу сообщений. Модельпередачи сообщений не вводит понятие разделяемого адресного пространства или непосредственногодоступа одного процессора к памяти другого - все не относящееся к передаче сообщений, находится внепарадигмы. Поскольку программы, выполняющиеся на отдельных процессорах, связаны, операции передачисообщений представляют собой вызовы подпрограмм.Для тех, кто имеет опыт работы с сетями, системами клиент-сервер или объектно-ориентированнымипрограммами, парадигма передачи сообщений не преподнесет ничего нового. С недавнего временипарадигма программирования с передачей сообщений стала популярной.
Одной из причин этого сталоувеличение числа платформ, поддерживающих модель передачи сообщений. Программы, написанные сиспользованием передачи сообщений, могут выполняться на распределенных многопроцессорныхкомплексах или системах с разделяемой памятью, сетях и даже на однопроцессорых системах. Применяяпарадигму, программист знает, что его алгоритмы должны быть в принципе переносимы на любуюплатформу, поддерживающую модель передачи сообщений.
Модель передачи сообщений популярна непотому, что достаточно проста, но потому, что она фундаментальна.Программирование в модели обработки данных – параллелизм по данным. Подробнее см. Вопросы 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. Критические секции. Двоичные и общие семафоры.Процессы для своей работы могут использовать логические и физические ресурсы вычислительнойсистемы и ее окружения, причем ресурсы могут быть: поделены между процессами и закрепленыпостоянно (на все время работы процесса) или использованы всеми или некоторыми процессами поочереди.
Некоторые ресурсы могут быть общими и допускать параллельное обслуживание процессов.Ресурс, который допускает обслуживание только одного процесса в текущее время, называетсякритическим ресурсом.Участки программы процесса, в которых происходит обращение к критическим ресурсам,называются критическими участками. Такие участки должны быть выполнены в режиме "взаимногоисключения", т.е. в каждый момент времени не более чем один процесс может быть занят выполнениемсвоего, критического относительно некоторого ресурса, участка.