Юниты. Принцип разработки многопоточных приложений

для раздела Блоги

С развитием информационных технологий, решаемые на компьютере задачи становятся все более глубокими и разносторонними. В связи с этим возрастает значение эффективных методов программирования, в частности параллельного подхода к организации работы компьютерных программ. Иногда под параллелизмом понимают не совсем то, чем он является. Возникают требования распараллелить сугубо последовательные процессы, представить их в параллельном виде. Не все распараллеливается, как можно распараллелить процесс ходьбы? Ведь чтобы передвигаться, надо сначала сделать шаг одной ногой, затем другой, и только чередование этих действий даст результат. Этот процесс не распараллеливается, ибо одно действие зависит и является следствием другого. Когда мы отходим от сугубо инженерных задач детерминированного характера и двигаемся к задачам общего порядка, то замечаем, что процессы носят независимый характер. Да, один человек передвигаясь, последовательно переставляет ноги, но те же самые действия независимо от первого делает другой человек. Можно сказать, что их последовательные действия происходят параллельно. Изменив масштаб решаемых задач, мы оказываемся в мире параллельных процессов. С помощью параллельного программирования не только ускоряется выполнение компьютерных программ, но происходит сближение принципа их устройства с реально существующими в действительности явлениями.
Действие компьютерной программы напоминают чтение книги: чтобы определить содержание текущей строки надо прочитать предыдущую. Со временем вырабатывается и становится основным определенный стиль программирования, его парадигма ложится в основу существования основных методов программирования. Единицей этого стиля является исполняемая команда. Команда существует в одномерном измерении: время до нее и время после нее, сама команда есть контекст настоящего или текущее состояние программы. Чтобы изменить привычный стиль программирования, необходимо ввести новое понятие программной единицы, — для определенности назовем — Юнит. Юнит является самостоятельно описываемой программной единицей со своими свойствами и способом взаимодействия, способной существовать как независимо, так и в альянсе с другими юнитами. Программирование с помощью юнитов изменяет стиль и подходы к реализации программного обеспечения. Компьютерная программа приобретает свойства происходящих в реальном мире процессов. Такой подход к программированию вообще идет в ногу с техническим прогрессом в области аппаратных средств, где современным процессором становится многоядерный процессор, способный согласованно выполнять несколько цепочек команд одновременно. Ликвидация разрыва между принципом организации выполнения команд многоядерного процессора и сложившимся стилем программирования позволяет при помощи программ более легко интерпретировать сложные реальные процессы. Программирование с использованием юнитов не упрощает программирование и не отменяет полностью понятие последовательного выполнения команд, скорее поднимает весь процесс конструирования программ на более высокий уровень.

Юниты

Юнит есть исполняющаяся в потоке на физически отдельном ядре совокупность методов, подчиняющаяся правилам взаимодействия и существования в системе как целое. Юнит является отдельным потоком, циклически реализующим в системе несколько методов. Методы передаются юниту в качестве входных параметров метода инициации юнита. Параметры функции инициализации юнита должны быть уникальными; два любых юнита не могут исполнять один и тот же экземпляр метода. Для исполнения одного метода в нескольких юнитах одновременно следует создать оператором new соответствующее количество экземпляров этого метода.

Юниты могут присутствовать в системе в одном из трех состояний: чистый клиент, чистый сервер и клиент-сервер. Юнит, не являющийся клиент-сервером, имеет исключительно либо исходящие, либо входящие связи. Инициацию взаимодействия всегда начинает юнит чистый сервер. Один юнит может соединяться с несколькими клиентами как сервер и одновременно быть клиентом для других серверов.



Логические особенности исполняющей системы

Юниты выполняются только в связанной системе, методы одиночного юнита (без связей) не исполняются. Для выполнения одиночного юнита, его следует определить как юнит чистый сервер и добавить связь с незаполненным функциональностью юнитом клиентом (заглушку). С логической точки зрения инициация взаимодействия сети юнитов выполняется клиентом. Однако, логика работы клиента построена так, что функционирование начинается при наличии сигнала готовности сервера. Это приводит к тому, что реально инициацию выполнит юнит чистый сервер. При отсутствии методов у юнита, логика его работы определенная статусом юнита не изменяется, пропускается только функциональная часть работы юнита.

При инициализации юнита создается уникальный идентификационный номер юнита. Юнит всегда имеет один неотрицательный идентификационный номер юнита. Юнит чистый клиент, при добавление связи к другому юниту, автоматически становится клиент-сервером. Юнит клиент-сервер при добавлении связи не изменяет свой статус, функционирование с новой связью возлагается на уже существующую у юнита серверную часть.
В общем случае, функционирование юнита заключается в исполнении трех методов F1, F2, F3. Юнит клиент-сервер может выполнять шесть методов: по три для каждой из своих сторон. Любой из методов является необязательным. Юнит сервер выполняет методы F1, F2 и приостанавливает дальнейшее выполнение в ожидании ответа от юнита клиента. Юнит клиент выполнив методы F1, F2 и F3 (если имеются) также приостанавливает свою работу и управление исполнением связки передается методу F3 юнита сервера. С этого момента цикл исполнения связки повторяется. Результаты исполнения каждого из методов, как сервера, так и клиента (возвращаемое оператором return значение метода) фиксируется в исполняющей системе и доступны как для главной программы (основного потока), так и для других юнитов.



Юнит сервер, связанный с несколькими клиентами перед выполнением метода F3 ожидает сигналов готовности от всех клиентов. Выполнение метода начинается после того как каждый клиент передаст сигнал готовности. Синхронизация подобного исполнения методов реализуется исполняющей системой и прозрачна для пользователя. Юнит, находящийся в двойном состоянии клиента и сервера первоочередно выполняет обязанности клиента по отношению к своему серверу, после этого выступает как сервер в другой связке юнитов. Таким образом достигается синхронная работа всех методов в цепи юнитов: от чистого сервера до чистого клиента и обратно.

Прекращение работы юнита обеспечивается командой директивного удаления юнита. Если удаляется юнит сервер, автоматически разрываются связи с клиентами. Юнит, оставшийся без всех связей, может опционально удаляться системой исполнения из рабочей среды. Для этого юниту или всей исполняющей среде (тогда автоматически требование распространяется на все юниты) задается опция – удалить юнит при отсутствии связей. Юнит, имеющий клиентскую часть, но утративший связи со всеми серверами, всегда не работает.



Технические особенности исполняющей системы

Физически каждый юнит исполняется строго на одном ядре многоядерного процессора. Операционная система не в состоянии перебросить исполнение методов юнита на другое ядро. Юниты выполняются на многоядерных процессорах таким образом, что не занимают ядро процессора с номером — 0. Такой подход принят в намерение добиться максимальной производительности исполняющей системы. В случае если исполнение методов могло бы осуществляться операционной системой на различных ядрах процессора, происходила бы потеря данных хранящихся в кеш L2. Возобновление исполнения методов потребует затрат времени на воссоздание информационной обвязки метода применительно к новому ядру, что неминуемо повлияет на производительность системы в целом.


Загрузка ЦП без перемещения потоков


Загрузка ЦП с перемещением потоков.

Потребность — не занимать исполняющей системой нулевое ядро процессора — обусловлена соображением обеспечения максимальной реактивности операционной системы относительно возникающих в исполнительной среде программных и аппаратных прерываний. Операционная система всегда должна иметь в своем распоряжении одно физическое ядро. На рисунках графически показан характер занятости ядер ЦП при отсутствии перемещения потоков и со свободным перемещением между ядрами в условиях одинаковой вычислительной нагрузки. Потоки, реализуемые исполнительной системой, не занимают нулевое ядро, однако, главный поток программы (точка входа метода main)может использовать нулевое ядро.

Исполняющая среда для ОС Windows способна задействовать от 8 до 64 ядер процессора. Ограничение на количество юнитов не налагается и определяется практической целесообразностью. Современные процессоры способны одновременно выполнять методы нескольких тысяч юнитов.

Программное обеспечение исполняющей среды представлено классами пространства имен – BindingAndServisParallel.

Исполнительная среда предоставляет способы потокобезопасного выполнения методов, обмена информацией между юнитами, средсва организации взаимодействия с элементами управления непосредственно из рабочих потоков.

Полная документация, библиотека классов и пример хранятся здесь в файлах DocCoreParallel.docx, BindingAndServiceCoreParallel, main.cs.

Пример компилируется в среде Visual Studio 2010 Express на 64-х битной платформе. При компиляции проекта следует добавить ссылки:

BindingAndServiceCoreParallel
PresentationCore
PresentationFramework
System
System.Xaml
WindowsBase

Библиотеку классов BindingAndServiceCoreParallel версия сборки 0.0.0.1 можно использовать без ограничения в любых целях.
Telegram-канал @overclockers_news - это удобный способ следить за новыми материалами на сайте. С картинками, расширенными описаниями и без рекламы.
Оценитe материал
рейтинг: 1.0 из 5
голосов: 3

Возможно вас заинтересует

Популярные новости

Сейчас обсуждают