Создание очереди заданий - Повышение производительности работы библиотеки GridMD
Для организации работы потоков был выбран паттерн проектирования Пул потоков (Thread Pool) [16] . Пул потоков является объектом, которому возможна выдача некоего множества задач на исполнение. Внутри пул потоков представляет собой ограниченный набор инициализированных потоков, которым пул раздает задачи на исполнение из очереди задач пула по мере ее заполнения в соответствии с конкретной схемой планирования назначения потоков на задачи. Поток в пуле может находиться в двух состояниях - ожидания получения задачи, когда поток спит, не занимая процессорное время, и состоянии непосредственного исполнения задачи. Задачи пулом по мере получения собираются в очереди задач и могут быть получены в любой момент существования пула. Пул гарантирует, что в определенный момент времени вновь пришедшая задача будет выполнена, когда до нее дойдет очередь.
Использование пула потоков для организации многопоточности по сравнению с механизмом выделения отдельного потока на каждую задачу ведет к лучшей стабильности и производительности работы приложения. Пул потоков решает проблему влияния накладных расходов по созданию и уничтожению потоков на производительность приложения, ведь потоки инициализируются в момент создания пула, который приводит их в непосредственную готовность для выполнения задач. Существование большого количество активных потоков при выделении отдельного потока на задачу чревато высоким потреблением системных ресурсов, ведь каждому потоку выделяется отдельная системная память, к тому же такие ресурсы как дескрипторы открытых файлов и сетевых соединений ограничены в выделении большому числу потоков. Смена контекста при переключении планировщиком потоков так же является затратной операцией. В пуле потоков, как правило, создается оптимальное количество потоков исходя из возможностей аппаратных средств по их физически параллельному исполнению, что сводит к минимуму затраты на смену контекста. Обычно, в пуле создается число потоков, равному числу ядер процессора исполняющего приложение, умноженному на два.
Использование пула потоков является оптимальным решением для распараллеливания выполнения локальных узлов в GridMD. Помимо преимуществ, указанных выше, использование пула в качестве отдельного модульного элемента позволяет инкапсулировать функционал по организации работы с задачами, генерируемыми менеджером сценариев, таким как ожидание завершения выполнения задачи, опрос статуса исполнения и получение результата задачи, в рамки одного компонента. Такой подход в реализации библиотеки виден в выделении отдельных компонентов, как менеджер сценариев и менеджер заданий. Для координирования исполнения задач в рамках потоков необходимо реализовывать отдельный менеджер, хорошим кандидатом на место которого выступает пул потоков (Рис. 8).
Рис. 8 Пул потоков в контексте компонентов GridMD
Взаимодействие с пулом происходит через его интерфейсные функции и состоит из отправки задачи на исполнение в очередь пула, опроса статуса исполнения задачи, ожидания завершения выполнения задачи с получением ее результата и отмены исполнения в случае необходимости. Логически, пул потоков является Вычислительным ресурсом для локальных задач, генерируемых менеджером сценариев. С точки зрения реализации пул не оформлен в виде ресурса, как это сделано с командным интерпретатором локальной операционной системы или удаленной системой очередей и нет необходимости указывать его в списке ресурсов в файле Resources. xml. Вместо этого, пользователь в секции настройки численного эксперимента при необходимости указывает, что локальные узлы могут быть выполнены с помощью пула, передавая значение перечислимого типа GmEXE_THREADS в метод GmExperiment::set_execution().
Пул потоков реализован в GridMD в виде класса GmThreadPool и в своей реализации имеет два основных компонента - класс рабочего потока GmThread и класс исполняемой задачи GmTask. При создании пулу потоков передается необходимое число рабочих потоков, которое по умолчанию равно числу ядер процессора, умноженному на два.
Рассмотрим более подробно интерфейс класса GmThreadPool:
- - Конструктор GmThreadPool (size_t threads=wxThread::GetCPUCount()-1) Инициализирует Threads рабочих потоков на исполнение в режим ожидания поступления новых задач в очередь задач. Параметром по умолчанию является оптимальное число потоков для данной аппаратной конфигурации, минус один, поскольку работа самого пула потоков выполняется в отдельном потоке, необходимость чего будет рассмотрена ниже. - ~gmThreadPool (). Деструктор пула потоков. Вызывается при выходе объекта пула потоков из области видимости, или явного удаления оператором Delete В случае выделения пула в динамической памяти. Немедленно останавливает все рабочие потоки, прерывая выполнение их текущих задач, освобождает связанные с потоками системные ресурсы и удаляет все оставшиеся задачи из очереди задач. - GmTaskID CreateGMMainTask (int (*gridmd_main)(int, char*[]), int argc, char* argv[]). Метод отправки пулу задачи по исполнению функции Int ((*gridmd_main)(int, char*[]), int argc). Пул потоков работает с абстракциям задач реализованных в виде класса GmTask и его наследников. Метод создает задачу в виде объекта класса GmMainTask, Наследника класса GmTask, Кладет задачу в очередь задач и устанавливает ей статус "принято на исполнение". Возвращает уникальный идентификатор принятой задачи GmTaskID, под которым задача регистрируется в пуле в реестре идентификаторов, и который возможно передать в другие интерфейсные функции пула для работы с конкретной задачей. - GmTASK_STATUS TaskStatus (gmTaskID taskID) const. Метод возвращает статус отправленной пулу задачи в виде перечислимого типа GmTASK_STATUS по уникальному идентификатору задачи TaskID. Поддерживаются следующие состояния задачи:
- ? GmTASK_POOLED - Задача принята на исполнение, в текущий момент ожидает исполнения в очереди задач. ? GmTASK_PROCESSED - Задача исполняется рабочим потоком. ? GmTASK_FINISED - задача успешно завершена, возможно получение ее возвращаемого значения с помощью метода Int TaskResult (gmTaskID taskID). ? gmINVALID_STATUS - Задача с идентификатором TaskID не зарегистрирована в пуле. Такое возможно, если идентификатор TaskID был получен не с помощью одного из методов пула по созданию задач, или задача была явно удалена из пула после вызова других методов, рассмотренных ниже.
Рассмотрим отдельные компоненты и некоторые детали реализации пула потоков.
Класс GmTask Является абстракцией задачи, выполняемой пулом потоков. gMTask Является абстрактным классом, от которого наследуются конкретные классы задач, реализуя чисто виртуальный метод GmTask::Run(). Метод Run() Позволяет определить действия, связанные с выполнением задачи, и исполняется рабочим потоком пула, когда до задачи доходит очередь. Таким образом, возможно определение различных типов задач и абстрагирование от их типа при исполнении в пуле. Типизация задач связанна с различными способами определения действий, связываемых с узлами графа исполнения.
Рис. 9 Диаграмма классов реализации пула потоков
В данный момент реализован класс GmMainTask для исполнения задачи, генерируемой менеджером сценариев, при Неявном определении действий, а именно для исполнения функции Gridmd_main(). В будущем планируется реализовать поддержку исполнения задач в пуле при явном определении действий с помощью класса GmNodeAction и при определении действий в виде скриптов.
Рис. 10 Диаграмма состояний объекта класса GmTask
На Рис. 10 представлена диаграмма состояний класса GmMainTask. Жизненный цикл задачи, исполняемой пулом, начинается с создания объекта GmTask и отправки задачи в очередь заданий пула с помощью метода GmThreadPool::GreateGMMainTask(). Задача переходит в состояние GmTASK_POOLED, При котором она ожидает своей очереди на исполнение. Когда задача становится в начале очереди, ее забирает первый освободившийся поток и вызовом метода GmThread::StartTask() начинает исполнение задачи, вызывая метод GmMainTask::Run() и устанавливая ее в состояние GmTASK_PROCESSED. После завершения метода GmMainTask::Run() исполнение задачи завершено, поток устанавливает состояние задачи в GmTASK_FINISHED и забирает новую задачу в случае, если очередь задач не пуста. В состоянии GmTASK_FINISED вызов метода GmThreadPool::TaskResult() Немедленно возвращает число, сигнализирующее об успешности выполнения задачи, в соответствии с логикой, заложенной пользователем, и удаляет объект GmMainTask Вместе с ее уникальным идентификатором из реестра идентификаторов пула. Пул не хранит информацию о выполненной и опрошенной о результатах задаче, и метод опроса статуса GmThreadPool::TaskStatus() по такому идентификатору вернет GmINVALID_STATUS.
В состояниях GmTASK_POOLED, gmTASK_PROCESSED, gmTASK_FINISHED Возможно явно отменить выполнение задачи и уничтожить связанный с ней объект методом GmThreadPool::RemoveTask(), который установит состояние задачи в GmINVALID_STATUS. Реализация механизма удаления состоит либо в удалении задачи из очереди в случае, если она находится в статусе GmTASK_POOLED, Или удалении связанного с ней потока при нахождении задачи в состоянии GmTASK_PROCESSED. Не существует другого способа отцепить задачу от рабочего потока пула, кроме явного удаления потока с освобождением связанных с ним ресурсов и его переинициализации. Но для восстановления исходного количества рабочих потоков после удаления задачи в классе пула потоков необходим механизм, который будет производить мониторинг текущего состояния потоков пула, получать сигнал об удалении задачи и инициализировать новый поток вместо удаленного. Именно поэтому класс GmThreadPool, как и его рабочие потоки GmThread, является наследником класса WxThread И переопределяет метод WxThread::Entry(), Который работает в отдельном потоке, ожидая сообщения об удалении рабочего потока и инициализируя новый вместо удаленного.
В приведена реализация восстановления количества рабочих потоков при удалении одного из них. Метод GmThreadPool:: Entry() Ожидает сигнала об удалении потока с помощью условной переменной MThreadsNotifier И ее метода Wait(). В деструкторе GmThread Происходит вызов MThreadNotifier. Signal(), Который будит ожидающий служебный поток пула, и проверяет условие равентва текущего количества потоков переданному пользователем при создании пула. Если они не равны, то служебный поток блокирует связанный с массивом потоков мьютекс, чтобы предотвравить конкуретный доступ к ней (при удалении еще одной задачи деструктор другого потока обратиться к масссиву для удаления себя из него), инициализирует необходимое количество потоков и добавляет их в массив.
При отсутствии в очереди задач каждый из рабочих потоков GmThread в переопределенном методе GmThread::Entry() ожидает сигнала о прибытии в очередь новой задачи с помощью условной переменной MQueueNotifier, входящей в состав объекта GmThreadPool, и ее метода Wait(). В методе GmThreadPool::SubmitTask(gmTask *task) Задача кладется в очередь, о чем сигнализируется одному из ожидающих потоков методом MQueueNotifier. Wait(). Кто именно из ожидающих потоков получит сообщение о получении новой задачи не определено и зависит от планировщика операционной системы, и в данной реализации это не имеет важности. После получения сообщения поток просыпается, блокирует связанный с очередью задач мьютекс MQueueMutex для получения эксклюзивного доступа к очереди задач и начинает выполнение задачи вызовом метода GmThread::StartTask(). После завершения выполнения задачи поток пытается взять новую задачу из очереди. В этом случае, если очередь не пуста, распределение задач по потокам определяется случайным образом и зависит от последовательности получения каждым из них исключительного доступа к критической секции путем блокировки мьютекса MQueueMutex. Поток, занявший критическую секцию, получает первую задачу из очереди.
Важной особенностью представленной реализации пула потоков является его модульность и высокая степень сокрытия реализации. Пул потоков самостоятельно управляет ресурсами, такими как рабочие потоки и задачи, выделяя их по внешнему запросу и освобождая по мере использования. Внешние компоненты, взаимодействующие с пулом (например, менеджер сценариев), не имеют доступа к объектам рабочих потоков GmThread и задач GmTask, им лишь выдаются идентификаторы для работы с ресурсами через интерфейс пула. Поддерживаемый набор типов задач так же является расширяемым через наследование от класса GmTask, интерфейс которого не зависит от других компонентов библиотеки GridMD. Таким образом, реализованный пул потоков имеет слабую связность с остальными компонентами библиотеки, не зависит от их реализации и может быть использован обособленно в других проектах.
Похожие статьи
-
В качестве доступного инструментария были рассмотрены две открытые кроссплатформенные библиотеки для разработки C++ приложений WxWidgets и Boost ,...
-
Библиотека GridMD поддерживает три механизма определения действий, связываемых с узлами графа [8]. Узел графа может соответствовать исполнению стороннего...
-
Обозначенные условия определяют работу по внедрению многопоточных средств в модели параллельного программирования С общей памятью с использованием...
-
Основные компоненты библиотеки - Повышение производительности работы библиотеки GridMD
Двумя главными компонентами библиотеки GridMD является менеджер сценариев и менеджер заданий (Рис. 4) [10]. Менеджер сценариев разбирает определенный...
-
В рамках данной работы будет произведена оптимизация выполнения Локальных узлов графа исполнения. В процессе исполнения графа возможна итерация, в...
-
Иерархия параллельных вычислительных систем - Повышение производительности работы библиотеки GridMD
Одной из основополагающих классификаций параллельных систем является Таксономия Флинна , в которой различаются следующие типы систем по взаимодействию...
-
Workflow-методология - Повышение производительности работы библиотеки GridMD
Суть workflow-методологии хорошо отражена в определении, данным Workflow Management Coalition [5] - это автоматизация бизнес процесса, при котором...
-
Одной из особенностей библиотеки GridMD является поддержка Алгоритмических шаблонов распределенных вычислений. Алгоритмические шаблоны являются...
-
Модель вычислительного процесса в GridMD - Повышение производительности работы библиотеки GridMD
Узлы графа исполнения, используемого в GridMD, представляют собой конкретные этапы исполнения, с которыми связываются действия, определяемые программным...
-
Заключение, Список используемых источников - Повышение производительности работы библиотеки GridMD
В работе произведена успешная оптимизация выполнения локальных узлов графа исполнения приложений, основанных на библиотеки GridMD. В качестве метода для...
-
Тестирование эффективности многопоточной реализации исполнения локальных узлов производилось на примере расчета определенного интеграла функции. Расчет...
-
Программное обеспечение промежуточного уровня (middleware) Является основной концепцией по организации программного обеспечения распределенных систем...
-
Общие сведения о библиотеке GridMD Библиотека GridMD является инструментом разработчика распределенных приложений [8][9][10]. Приложение, разделяемое на...
-
Введение - Повышение производительности работы библиотеки GridMD
На сегодняшний день уровень развития вычислительной техники и средств доступа к вычислительным ресурсам предоставляет значительные возможности по...
-
Общие сведения о распределенных вычислениях Обычно под Распределенными вычислениями понимают область знаний, изучающую организацию Распределенных систем...
-
Механизм исполнения GridMD приложения - Повышение производительности работы библиотеки GridMD
Управление исполнением графа осуществляется обособленно из Клиентского приложения, осуществляющего вызовы интерфейсных функций библиотеки GridMD [8]....
-
ЭВМ обслуживает три терминала по круговому циклическому алгоритму, предоставляя каждому терминалу 30 с. Если в течение этого времени задание...
-
Цель Работы - изучить приемы создания и использования шаблонов классов. - Теоретические сведения Достаточно часто встречаются классы, объекты которых...
-
SimpleXML. В PHP версии 5.0 и выше появилось расширение для работы с xml структурой. Библитека SimpleXML содержит большое количество методов для работы с...
-
Цель Работы - изучить одну из базовых концепций ООП, наследование классов в С++, заключающуюся в построении цепочек классов, связанных иерархически,...
-
Цель Работы - изучить основные способы работы с пользовательским типом данных "класс", его объектами, методами и способы доступа к ним. - Теоретические...
-
2.1 Среды разработки для построения программных агентов Инструментальные средства разработки программных агентов формируют среду, которая оптимизирована...
-
Цель Работы : приобрести начальные знания в области применения микроконтроллеров и основ цифровой техники. Теоретические сведения и выполнение работы...
-
Повышение производительности дисководов с помощью утилиты Speed Disk (SPEEDISK)
Лабораторная работа № 5 Тема: Повышение производительности дисководов с помощью утилиты Speed Disk (SPEEDISK). Цель: Освоить приемы обеспечения повышения...
-
Осуществление всего комплекса работ по созданию должно осуществляться в несколько очередей. Спецификация работ по созданию первой очереди АС в объеме...
-
Построение аналитической модели АОУ затруднено из-за отсутствия или недостатка априорной информации об объекте управления, а также из-за ограниченности и...
-
Как отмечалось, входной язык системы MathCAD -- интерпретирующий. В интерпретаторах, например в добром старом Бейсике, листинг программы пользователя...
-
Выполнение функции добавление человека в базу данных По нажатию на кнопку "Добавить" или сочетанием клавиш Ctrl+A произойдет добавление человека в базу...
-
Задание 3. Создание Web-страниц в PowerPoint - PowerPoint и презентация
Программа PowerPoint, входящая в состав Microsoft Office, позволяет на профессиональном уровне подготовить слайды для проведения презентаций. Благодаря...
-
Структурная схема терминов Организация предпроектного обследования Предпроектная стадия включает комплекс научно-исследовательских работ и...
-
Модуль - Самостоятельно компилируемый файл ТР, который может содержать описание констант, переменных и типов, процедур и функций. Он имеет имя и хранится...
-
Принцип работы языка. Синтаксис Как и было сказано ранее основой для HTML-были приняты текстовые документы, содержащие в себе HTML5. Рассмотрим следующий...
-
Определить наилучшие параметры корректирующего устройства следящей системы, обеспечивающих устойчивость системы и выполнение требований технического...
-
Программный интерфейс для базы данных я разрабатывал в объектно-ориентрованной среде Delphi, с помощью Embarcadero RAD Studio. Конструктор форм Delphi в...
-
Система отслеживания ошибок (англ. bug tracking system) - прикладная программа, разработанная с целью помочь разработчикам программного обеспечения...
-
Концепция решает три задачи: Определить основные идеи и направления развития и согласовать их с клиентом. Получить оценку этих идей от будущих...
-
Метод конечных элементов (МКЭ) жесткости возник в аэрокосмической отрасли. Исследователи рассматривали различные подходы к анализу сложных частей...
-
Построение модели сердца, Постановка задачи, Создание нового проекта - Построение модели сердца
Постановка задачи Мы рассмотрим простейшую математическую модель, описывающую процессы, похожие на биение сердца. Эта модель описана двумя...
-
На чем основана работа программы - Rational Rose для разработчиков
Итак, от общих тем перейдем непосредственно к тому, что умеет делать CASE Rational Rose. Являясь объектно-ориентированным инструментом моделирования,...
-
OpenGL - это программный интерфейс к графической аппаратуре. Этот интерфейс состоит приблизительно из 250 отдельных команд (около 200 команд в самой...
Создание очереди заданий - Повышение производительности работы библиотеки GridMD