Система программированния ИНЯ/С

advertisement
Ðîññèéñêàÿ Àêàäåìèÿ Íàóê • Ñèáèðñêîå Îòäåëåíèå
Âû÷èñëèòåëüíûé Öåíòð
Îòäåë ìàòåìàòè÷åñêîãî îáåñïå÷åíèÿ âûñîêîïðîèçâîäèòåëüíûõ âû÷èñëèòåëüíûõ ñèñòåì
Ëàáîðàòîðèÿ ñèíòåçà ïàðàëëåëüíûõ ïðîãðàìì
Система параллельного программирования Иня/Си
для мультикомпьютера IBM PC AT / TMS320.
Описание реализации.
Содержание.
Введение. ----------------------------------------------------------------------------------------------------------------------------------------------------- 1
Раздел 1. Организация параллельных вычислений. ------------------------------------------------------------------------------------------- 1
1.1. Архитектура МВС. ------------------------------------------------------------------------------------------------------------------------------------------------------1
1.2. Модель параллельных вычислений. -----------------------------------------------------------------------------------------------------------------------------3
1.3. Модули параллельных программ. --------------------------------------------------------------------------------------------------------------------------------4
Раздел 2. Средства программирования. ----------------------------------------------------------------------------------------------------------- 5
2.1. Инструментальные средства разработки программ. ------------------------------------------------------------------------------------------------------5
2.2. Средства поддержки параллельных вычислений. ----------------------------------------------------------------------------------------------------------6
2.3. Операторы Иня/Си. ----------------------------------------------------------------------------------------------------------------------------------------------------6
2.3.1. Инициирование и завершение системы параллельных вычислений. -------------------------------------------------------------------------6
Init -------------------------------------------------------------------------------------------------------------------------------------------------------------------------6
Done ----------------------------------------------------------------------------------------------------------------------------------------------------------------------6
2.3.2. Формирование параллельных процессов. --------------------------------------------------------------------------------------------------------------7
ParDo---------------------------------------------------------------------------------------------------------------------------------------------------------------------7
ParEnd -------------------------------------------------------------------------------------------------------------------------------------------------------------------7
2.3.3. Формирование критических программных областей. -----------------------------------------------------------------------------------------------8
Sect -----------------------------------------------------------------------------------------------------------------------------------------------------------------------8
Post -----------------------------------------------------------------------------------------------------------------------------------------------------------------------8
2.3.4. Синхронизация. --------------------------------------------------------------------------------------------------------------------------------------------------9
Wait -----------------------------------------------------------------------------------------------------------------------------------------------------------------------9
2.3.5. Равномерная загрузка процессов. -------------------------------------------------------------------------------------------------------------------------9
SnipHor ------------------------------------------------------------------------------------------------------------------------------------------------------------------9
2.4. Интерфейсные функции библиотеки подчиненных модулей. ----------------------------------------------------------------------------------------- 10
2.5. Служебные функции исполняющей системы. -------------------------------------------------------------------------------------------------------------- 10
2.6. Служебные функции диспетчера параллельных вычислений. --------------------------------------------------------------------------------------- 10
2.7. Функции формирования заданий и включения их в очереди процессов. ------------------------------------------------------------------------- 10
PE_QRun() ----------------------------------------------------------------------------------------------------------------------------------------------------------- 11
PE_QPutDataAddr() ------------------------------------------------------------------------------------------------------------------------------------------------ 11
PE_QGetDataAddr() ----------------------------------------------------------------------------------------------------------------------------------------------- 11
PE_QPutValAddr()-------------------------------------------------------------------------------------------------------------------------------------------------- 11
PE_QSect() ----------------------------------------------------------------------------------------------------------------------------------------------------------- 11
PE_QPost() ----------------------------------------------------------------------------------------------------------------------------------------------------------- 11
PE_QExec() ---------------------------------------------------------------------------------------------------------------------------------------------------------- 12
2.8. Функции поддержки параллельных вычислений для программных модулей TMS320. ------------------------------------------------------ 12
SetReady() ------------------------------------------------------------------------------------------------------------------------------------------------------------ 12
ConvPCtoTMS() ----------------------------------------------------------------------------------------------------------------------------------------------------- 12
ConvTMStoPC() ----------------------------------------------------------------------------------------------------------------------------------------------------- 13
Раздел 3. Примеры. ------------------------------------------------------------------------------------------------------------------------------------- 13
3.1.Процедура parmmul - параллельное умножение матриц. ---------------------------------------------------------------------------------------------- 13
parmmul.cpp ---------------------------------------------------------------------------------------------------------------------------------------------------------- 13
test1.cpp --------------------------------------------------------------------------------------------------------------------------------------------------------------- 14
3.2. Программа largmmul - параллельное умножение матриц, не вмещающихся в оперативную память ПЭВМ. --------------------- 15
largmmul.cpp --------------------------------------------------------------------------------------------------------------------------------------------------------- 15
3.3.Реализация подчиненного программных модуля mmul. ------------------------------------------------------------------------------------------------ 17
_mmul.c ---------------------------------------------------------------------------------------------------------------------------------------------------------------- 17
_mmul.bat ------------------------------------------------------------------------------------------------------------------------------------------------------------- 18
_mmul.cmd------------------------------------------------------------------------------------------------------------------------------------------------------------ 18
_mmul.map ----------------------------------------------------------------------------------------------------------------------------------------------------------- 18
math_tms.h ----------------------------------------------------------------------------------------------------------------------------------------------------------- 19
Список литературы. ------------------------------------------------------------------------------------------------------------------------------------- 20
Íîâîñèáèðñê,1994
Èíÿ/Ñè. Îïèñàíèå ñèñòåìû. Âåðñèÿ îò 1/18/2016, ñòð. 1
Введение.
Мультикомпьютерная вычислительная система (МВС), включающая в себя центральную ПЭВМ типа
IBM PC AT и набор процессорных модулей семейства TMS320, предназначена для решения широкого
круга вычислительных задач. Основной проблемой при организации параллельных вычислений МВС
является отсутствие стандартных инструментальных средств, ориентированных на данную архитектуру
вычислительной системы, поддерживающих параллельное исполнение вычислительных процессов в
языках программирования высокого уровня.
Для решения данной проблемы лабораторией синтеза параллельных программ была разработана
система программирования Иня/Си, предлагающая средства параллельного программирования для
языков Си и Си++. Иня/Си реализована как расширение стандартного набора операторов языка Си
(Си++) и предоставляет пользователю все необходимые средства для организации параллельных
вычислений, позволяющие полностью использовать вычислительные ресурсы МВС. Система также
может быть использована как библиотека времени выполнения в языках ФОРТРАН, ПАСКАЛЬ и других
языка программирования. Достоинством системы является возможность использования стандартных
инструментальных пакетов ПЭВМ IBM PC AT как среду для разработки и отладки параллельных
программ; при этом не накладывается никаких ограничений на использование инструментальных средств,
предоставляемых данными пакетами.
Описываемый макет системы включает в себя: исполняющую систему параллельных операторов,
расширяющих язык Си; диспетчер, управляющий выполнением параллельных процессов; набор функций,
позволяющий организовывать параллельные вычисления без обращения к параллельным операторам,
эти функции могут использоваться для организации параллельных вычислений в других языках
программирования (ФОРТАН, ПАСКАЛЬ); программные средства поддержки параллельных процессов
TMS320.
Иня/Си сохраняет преемственность модели параллельных вычислений и поддерживает основные
параллельные операторы языка “Иня” [2].
Предлагаемое описание системы состоит из 3-х разделов:
Раздел 1 - архитектура и основные характеристики МВС; реализуемая модель параллельных
вычислений; описание работы диспетчера параллельных процессов;
Раздел 2 - описание параллельных операторов и функций;
Раздел 3 - примеры использования системы.
В описании основное внимание уделено вопросам программной реализации системы.
Раздел 1. Организация параллельных вычислений.
1.1. Архитектура МВС.
Рассматриваемая МВС объединяет аппаратный модуль центрального процессора (ЦП) семейства
iAPX 286/386/486, оперативную память (ОП), и один либо несколько аппаратных модулей процессорных
элементов (ПЭ) семейства TMS320, содержащих блоки локальной оперативной памяти (ЛП) в каждом из
модулей. Обмен данными между блоками ОП и ЛП производится по радиальной схеме ОП-ЛП с помощью
устройства прямого доступа к памяти. Периферийные устройства ПЭВМ (клавиатура, терминал, дисковые
накопительные устройства и др.) доступны только со стороны ПЭ.
Èíÿ/Ñè. Îïèñàíèå ñèñòåìû. Âåðñèÿ îò 1/18/2016, ñòð. 2
Локальная
память (ЛП)
Процессорный
элемент (ПЭ)
1-й модуль ПЭ
Центральный
процессор (ЦП)
Оперативная
память (ОП)
Локальная
память (ЛП)
Процессорный
элемент (ПЭ)
...
Периферийные
устройства
Локальная
память (ЛП)
Модуль ЦП
2-й модуль ПЭ
Процессорный
элемент (ПЭ)
n-й модуль ПЭ
Рис. 1. Аппаратные модули и потоки данных МВС.
МВС позволяет одновременно исполнять несколько вычислительных процессов, где каждый из
процессов исполняется отдельным процессорным модулем. При этом ЦП и ПЭ имеют доступ к блокам
памяти только собственного модуля в собственном адресном пространстве. Обмен данными между
блоками памяти, загрузка исполняемого кода и запуск программных модулей на выполнение
производится по инициативе ЦП.
МВС предназначена для решения широкого круга вычислительных задач и является относительно
недорогой высокопроизводительной ЭВМ с возможностью динамически наращивать количество
процессорных модулей. Дополнительные процессорные модули в стандартные слоты центральной
ПЭВМ.
При использовании модулей процессора TMS320C30-33 высокая производительность МВС
обеспечивается:
- большой тактовой частотой процессора - 33 МГц,
- параллельной работой устройств арифметико-логических операций, умножения и адресных
вычислений/выборки,
- конвейерным выполнением инструкций процессора,
- возможностью одновременного выполнения 2-х различных инструкций,
- однотактовым выполнением арифметических и логических операций,
- большой разрядностью арифметических операций - 32 бит для операций с целыми числами и
плавающей запятой (40 бит для промежуточных вычислений),
- 64-х словным кэшем инструкций с динамической подзагрузкой наиболее часто исполняемых
участков кода,
- 32-разрядной внутримодульной шиной данных,
- наличием в составе процессорного модуля блока оперативной памяти общим объемом 1 Мслово
(4 Мбайта) и временем доступа 180 нс.
Производительность одного процессорного модуля TMS320C30-33 достигает 16.7 MIPS / 33.3
MFOLPS
[1],
и
общая
производительность
МВС
при
полной
загрузке
равна
суммарной
производительности всех установленных модулей. При этом производительность центральной ПЭВМ
слабо влияет на характеристики системы в целом, что позволяет использовать маломощные компьютеры
AT 286 без существенного снижения общей производительности системы.
Èíÿ/Ñè. Îïèñàíèå ñèñòåìû. Âåðñèÿ îò 1/18/2016, ñòð. 3
1.2. Модель параллельных вычислений.
Модель вычислений Иня/Си предполагает совместное исполнение нескольких вычислительных
процессов. Вычислительным процессом мы называем последовательное выполнение инструкций
некоторым аппаратным модулем фон-неймановской архитектуры, входящим в состав вычислительной
системы (см. Рис. 1). Вычислительные процессы Иня/Си разделяются на два основных класса:
1. Главный (управляющий) процесс, исполняемый модулем ЦП. Такой процесс всегда только один.
2. Один либо несколько подчиненных процессов, исполняемых модулями ПЭ. Подчиненные
процессы порождаются главным процессом.
Порождение подчиненных процессов производится в несколько этапов:
1-й этап - инициирование системы параллельных вычислений. Главный процесс формирует
набор специальных программных управляющих структур, называемых логическими процессами.
Логические процессы (или просто процессы) содержат информацию, необходимую для организации
подчиненных процессов. Количество процессов
определяется в момент инициации системы
параллельных вычислений и остается фиксированным до ее завершения. При этом каждый логический
процесс
всегда
отображается
на
свой
собственный
аппаратный
модуль
ПЭ,
т.е.
имеется
взаимооднозначное соответствие между логическими процессами, подчиненными процессами и
аппаратными модулями ПЭ:
Логические процессы  Подчиненные процессы  Модули ПЭ
Статическое отображение процессов на ПЭ имеет как преимущества, так и недостатки.
Преимущества:
- уменьшаются накладные расходы на обслуживание процессов;
- имеется возможность статической загрузки перед началом вычислений исполняемого кода
подчиненных процессов в ЛП и статического распределения ЛП под исполняемый код и данные;
- ЛП может использоваться для расширения общей оперативной памяти и хранения промежуточных
данных.
Недостатки:
- необходимо явно учитывать в программном алгоритме отображение процессов на ПЭ;
- количество процессов не может превышать количество доступных ПЭ.
2-й этап - формирование параллельных процессов. Каждому процессу назначается собственная
очередь заданий. Под заданием подразумевается одно из действий:
- передача данных между ОП и ЛП;
- загрузка исполняемого кода подчиненного процесса в ЛП и/или запуск его на выполнение;
- другие действия.
В момент формирования процессов все очереди заданий пусты. Задания формируются и
помещаются в очереди главным процессом с помощью вызова специальных функций исполняющей
системы Иня/Си. Каждый вызов функции добавляет одно задание в очередь одного из процессов.
Последовательности вызовов функций исполняющей системы могут объединяться в специальные
интерфейсные функции, скрывающие от пользователя детали управления заполнением очередей
заданий.
Динамические очереди заданий обеспечивают полный контроль со стороны главного процесса над
их формированием в период выполнения программы. Это позволяет создавать программные алгоритмы,
где формирование очередей зависит от параметров, которые становятся известны только после начала
выполнения программы.
Èíÿ/Ñè. Îïèñàíèå ñèñòåìû. Âåðñèÿ îò 1/18/2016, ñòð. 4
С другой стороны, сам процесс обслуживания (заполнение и диспетчеризация) очередей заданий
требует определенных накладных расходов со стороны главного процесса.
3-й этап - совместное исполнение процессов. После того, как очереди заданий сформированы,
главный
процесс
может
передать
управление
диспетчеру
параллельных
вычислений
(диспетчеризации). Диспетчер последовательно выбирает задания из очередей процессов и
осуществляет все необходимые действия для их выполнения и синхронизации подчиненных процессов.
Главный цикл диспетчера производит следующие действия:
а. Выбирает 1-й процесс.
б. Если очередь заданий пуста или признак занятости процесса установлен, переходит к п. е.
в. Выполняет задание из вершины (по дисциплине FIFO) очереди процесса и удаляет его оттуда.
г. Если задание запускает подчиненный процесс на выполнение, устанавливается признак занятости
процесса. Признак занятости сбрасывается порожденным подчиненным процессом в момент его
завершения.
д. Переходит к п. б.
е. Если обслуживаемый процесс не последний, то выбирает следующий процесс и переходит к п. б.
ж. Если все очереди заданий пусты и все признаки занятости сброшены, завершает
диспетчеризацию; иначе переходит к п. а.
Приведенный алгоритм диспетчеризации обеспечивает выполнение следующих условий:
- задания процесса выполняются строго последовательно,
- порядок выполнения заданий различных процессов недетерминирован и определяется только
состоянием готовности процесса,
- подчиненные процессы выполняются параллельно друг с другом и с главным процессом.
Вышесказанное
позволяет
рассматривать
модель
вычислений
Иня/Си
как
параллельное
исполнение процессов [3].
1.3. Модули параллельных программ.
С точки зрения построения программного обеспечения программа для МВС разбивается на главный
(программный) модуль, включающий исполняемый код главного процесса, и ряд подчиненных
(программных) модулей, содержащих исполняемый код подчиненных процессов. Главный модуль
запускается на выполнение средствами операционной системы ПЭВМ и осуществляет все действия по
управлению вычислениями. Главный модуль:
- является независимым программным модулем с точки зрения операционной системы ПЭВМ,
начинает и завершает выполнение программы;
- выполняет операции ввода/вывода;
- инициирует аппаратные и программные средства параллельных вычислений;
- управляет заполнением очередей заданий;
- осуществляет диспетчеризацию процессов.
Исполняемый
код
подчиненных
модулей
запускается
на
выполнение
главным
модулем.
Подчиненные программные модули:
- используют в вычислениях данные из своих локальных блоков памяти; эти данные загружаются из
ОП заданиями процесса;
- осуществляют конверсию различных машинных форматов данных в ЛП;
Èíÿ/Ñè. Îïèñàíèå ñèñòåìû. Âåðñèÿ îò 1/18/2016, ñòð. 5
- в случае последовательного выполнения нескольких процессов на одном ПЭ, используют
промежуточные результаты (данные), хранящиеся в ЛП данного ПЭ;
- помещают результаты вычислений в ЛП; эти результаты затем передаются в ОП заданиями
процесса;
- уведомляют диспетчер (сбрасывают специальный признак занятости) об окончании процесса
вычислений.
Схематично процесс вычислений главного программного модуля выглядит так:
а. С помощью операций ввода/вывода в ОП вводятся исходные данные.
б. Инициируется система параллельных вычислений.
в. Последовательно формируются и помещаются в очередь процесса задания:
- набор заданий для передачи исходных данных в ЛП;
- загрузки исполняемого кода подчиненного модуля (если он не загружен ранее);
- запуска исполняемого кода подчиненного модуля на выполнение;
- набор заданий для считывания результатов в ОП.
г. При необходимости повторяются шаги п. в для последовательного исполнения нескольких
подчиненных модулей в одном процессе. В этом случае, если результаты счета модуля используются как
исходные данные следующим модулем, то задания на передачу данных в ЛП могут отсутствовать. Если
эти данные используются только подчиненными модулями, то могут отсутствовать задания на их
считывание в ОП.
д. Шаги п.п. в и г повторяются для каждого процесса.
е. Запускается главный цикл диспетчера для выполнения сформированных процессов.
ж. При необходимости повторяются шаги п.п. в-е для реализации алгоритма вычислений.
з. Завершается работа системы параллельных вычислений.
и. Результаты вычислений выводятся с помощью операций ввода/вывода.
Последовательности действий п. в обычно включаются в интерфейсные функции, упрощающие
подготовку последовательности заданий для формирования вычислений подчиненного процесса.
Шаги п.п. б-з могут целиком быть вынесены в отдельную процедуру, локализующую все действия по
управлению параллельными вычислениями (см. пример из п. 3.1).
Раздел 2. Средства программирования.
2.1. Инструментальные средства разработки программ.
Программные модули для работы с системой Иня/Си разрабатываются с помощью следующих
средств:
1. Инструментальная система (ИС) разработки программ на языке Си для ПЭВМ IBM PC AT. В
качестве ИС может использоваться пакет Borland C++ 3.0 или любой другой, поддерживающий стандарт
ANSI C [4] либо проект стандарта ANSI C++ [5]. Система Иня/Си предоставляет специальные средства
поддержки параллельных вычислений для программ на языках Си и Си++.
2. Набор инструментальных средств разработки программ на языке Си для процессора TMS320. В
набор должны входить компилятор языка Си, ассемблер, компоновщик, библиотеки функций и др.
средства. Программные модули TMS320 для работы с системой Иня/Си должны удовлетворять
ограничениям системы DAOS-30 [6]. Иня/Си предоставляет функции поддержки параллельных
вычислений для программных модулей TMS320.
Èíÿ/Ñè. Îïèñàíèå ñèñòåìû. Âåðñèÿ îò 1/18/2016, ñòð. 6
2.2. Средства поддержки параллельных вычислений.
Средства поддержки параллельных вычислений включают в себя:
1. Средства высокого уровня:
- операторы расширения языка Си (п. 2.3) для реализации параллельных конструкций Иня/Си;
операторы реализованы в виде стандартных макроопределений ANSI C;
- интерфейсные функции библиотеки подчиненных модулей (п. 2.4).
2. Средства среднего уровня:
- служебные функции исполняющей системы (п. 2.5);
- служебные функции диспетчера параллельных вычислений (п. 2.6);
- функции формирования заданий и включения их в очереди процессов (п. 2.7).
3. Средства низкого уровня:
- функции методов доступа к модулям TMS320.
4. Средства поддержки параллельных вычислений для программных модулей TMS320:
- функции поддержки параллельных вычислений (п. 2.8);
- библиотека подчиненных модулей; подчиненные модули имеют формат загрузочных .out файлов
[1] процессора TMS320.
В инструментальные средства системы Иня/Си также входит утилита maph30.com, позволяющая
обращаться из главного программного модуля к глобальным переменным подчиненных модулей по их
символьным именам.
Все реализации функций включены в специальные библиотеки объектных модулей Иня/Си и
сопровождены .h файлами заголовков.
2.3. Операторы Иня/Си.
Макроопределения параллельных операторов Иня/Си находятся в файле inya.h.
2.3.1. Инициирование и завершение системы параллельных вычислений.
Init
Оператор Init инициирует систему управления параллельными вычислениями.
Оператор Init формирует и инициализирует специальные управляющие структуры исполняющей
системы Иня/Си и должен быть выполнен до использования любых других параллельных конструкций.
Init формирует логический процесс для каждого доступного ПЭ (но не более чем nPcsMax). ПЭ считается
доступным, если его модуль установлен в слот ПЭВМ и тестирование модуля не выявило его
неисправности.
Параметры
nPcsMin - минимальное необходимое количество ПЭ;
nPcsMax - максимальное количество ПЭ.
Возвращает
количество сформированных логических процессов или 0, если количество доступных ПЭ оказалось
меньше nPcsMin.
Done
Оператор Done завершает работу системы управления параллельными вычислениями, освобождая
ресурсы, занятые системой.
Èíÿ/Ñè. Îïèñàíèå ñèñòåìû. Âåðñèÿ îò 1/18/2016, ñòð. 7
Оператор Done должен быть выполнен только после завершения всех параллельных вычислений.
Оператор Done также должен выполняться в случае аварийного завершения программы.
2.3.2. Формирование параллельных процессов.
ParDo
Оператор ParDo начинает блок формирования параллельных вычислений (БФПВ).
Пара операторов ParDo и ParEnd ограничивают БФПВ, обеспечивая формирование параллельных
процессов. Программный текст, ограниченный БФПВ, последовательно выполняется nPcs раз, формируя
процессы с индексами Ind от 1 до nPcs. Все запросы на постановку в очередь заданий (см. п. 2.7) внутри
БФПВ помещают задания в очередь процесса с соответствующим индексом.
Параметры
nPcs - количество формируемых процессов; nPcs должно быть <= количества логических процессов;
Ind - переменная текущего индекса процесса.
ParEnd
Оператор ParEnd завершает БФПВ.
Если в программе имеется оператор ParDo, то обязательно должен присутствовать и парный
завершающий оператор ParEnd.
Реализация
//***** Реализация ParDo *****
int Ind;
for( Ind = 1; Ind <= nPcs; Ind++ )
{ PE_SetProc( Ind );
// устанавливаем индекс формируемого процесса
...
//***** Реализация ParEnd *****
}
Пример
ParDo( 3, I )
if( I == 2 )
PE_QRun( “Task1” );
else
PE_QPutValAddr( “Task2” );
PE_QRun( “Task3” );
if( I == 2 )
PE_QRun( “Task4” );
ParEnd
Очереди заданий процессов после завершения БФПВ выглядят так:
Èíÿ/Ñè. Îïèñàíèå ñèñòåìû. Âåðñèÿ îò 1/18/2016, ñòð. 8
Процесс 1:
Run( “Task1”)
Run( “Task3”)
Процесс 2:
Run( “Task2”)
Run( “Task3”)
Run( “Task4”)
Процесс 3:
Run( “Task1”)
Run( “Task3”)
2.3.3. Формирование критических программных областей.
Sect
Оператор Sect начинает формирование критической программной области (КПО). Критической
программной областью называется набор последовательно выполняемых заданий процесса, во время
выполнения которых запрещено выполнение критических областей любых других процессов.
Пара операторов Sect и Post ограничивают КПО, гарантируя последовательное исполнение заданий
из КПО различными процессами; если процесс занял КПО (выполнил задание Sect), то любой другой
процесс, требующий входа в КПО (выполнения задания Sect) будет ждать, пока процесс, занявший КПО,
его не освободит (выполнит задание Post). Т.о. КПО может быть занят только одним процессом и
процессы, требующие входа в КПО, будут занимать его строго последовательно. Порядок, в котором
различные процессы занимают КПО, не детерминирован.
Post
Оператор Post завершает КПО.
Если в программе имеется оператор Sect, то обязательно должен присутствовать парный
завершающий оператор Post.
Реализация
//***** Реализация Sect *****
{ PE_QSect(); // помещаем в очередь формируемого процесса задание Sect
...
//***** Реализация Post *****
PE_QPost(); // помещаем в очередь формируемого процесса задание Post
}
Модификация главного цикла диспетчера
Для реализации механизма КПО в главный цикл диспетчера (см. п. 1.2) должны быть добавлены
п. б1 после п. б и п. в1 после п. в:
б1. Если задание в вершине очереди - Sect и КПО занят, переходит к п. е.
в1. Задание Sect устанавливает, а Post сбрасывает признак занятости КПО.
Пример
ParDo( 3, I )
PE_QRun( “task0” );
Sect
char buffer[ 6 ];
sprintf( buffer, “task%i”, I );
PE_QRun( buffer );
sprintf( buffer, “task%i”, I + 3 );
PE_QRun( buffer );
Post
ParEnd
Очереди заданий процессов после завершения БФПВ выглядят так:
Èíÿ/Ñè. Îïèñàíèå ñèñòåìû. Âåðñèÿ îò 1/18/2016, ñòð. 9
Процесс 1:
Процесс 2:
Run( “task0” )
Run( “task0” )
Sect
Sect
Run( “task1” )
Run( “task2” )
Run( “task4” )
Run( “task5” )
Post
Post
Здесь гарантируется, что во время последовательного
Процесс 3:
Run( “task0” )
Sect
Run( “task3” )
Run( “task6” )
Post
выполнения заданий с номерами i и i+3,
i = 1..3, выполнение любого задания j или j+3, j = 1..3, j  i невозможно. Например, если в какой-то
момент времени задание Run( “task2” ) было запущено на выполнение, то ни одно из заданий
Run( “task1” ), Run( “task3” ) не может выполняться, и процессы 1 и 3 будут ждать завершения задания
Run( “task5” ).
2.3.4. Синхронизация.
Wait
Оператор Wait запускает диспетчеризацию процессов и ждет, пока все задания из очередей процессов
не выполнятся.
Оператор Wait всегда должен выполняться после БФПВ, так как БФПВ только подготавливает
очередь заданий процессов и не обеспечивает собственно их выполнения.
Реализация
while( PE_State() != PE_READY )
PE_Exec();
// пока хотя бы одна очередь не пуста
// или хотя бы один процесс не завершен,
// выполняем итерации главного цикла диспетчера
2.3.5. Равномерная загрузка процессов.
SnipHor
Оператор SnipHor возвращает информацию, позволяющую разрезать массивы данных на (примерно)
одинаковые горизонтальные полосы, количество которых равно количеству параллельных процессов.
Параметры
nRows - количество строк в массиве;
Offset - переменная номера строки (нумеруются с 0) начала текущей полосы;
Lenght - переменная количества строк в текущей полосе.
Реализация
int Offset, Lenght;
{
// описание nPcs и Ind см. в описании переменных оператора ParDo
int l = ( nRows - 1 ) / nPcs + 1;
// максимальная ширина полосы
int n = ( nRows - 1 ) % nPcs + 1;
// количество полос с максимальной шириной
Offset = l * ( Ind - 1 ) - ( Ind - 1 - n > 0 ) ? ( Ind - 1 - n ) : 0;
Lenght = l - ( Ind - n > 0 ) ? 1 : 0; }
Пример
ParDo( 5, I )
SnipHor( 48, Ofs, Len )
...
ParEnd
Значения переменных Ofs и Len для различных I, возвращаемые SnipHor:
Èíÿ/Ñè. Îïèñàíèå ñèñòåìû. Âåðñèÿ îò 1/18/2016, ñòð. 10
I
Ofs
Len
Полоса
1
2
3
4
5
0
10
20
30
39
10
10
10
9
9
с 0-й по 9-ю строки
с 10-й по 19-ю строки
с 20-й по 29-ю строки
с 30-й по 38-ю строки
с 39-й по 47-ю строки
2.4. Интерфейсные функции библиотеки подчиненных модулей.
Библиотека подчиненных модулей в настоящий момент включает 2 модуля:
Модуль
mmul
vadd
Описание
вычисление произведения матриц
сложение векторов
Интерфейсная функция
mmul_tms
vadd_tms
.out-файл
_mmul.out
_vadd.out
Заголовки интерфейсных функций находятся в файле math_tms.h.
2.5. Служебные функции исполняющей системы.
Заголовок функции
LOGPROC PE_Init( LOGPROC minProc,
LOGPROC maxProc );
void PE_Done();
void PE_SnipHor( int nRows,
int *pnOffset, int *pnLenght );
Описание
инициирует исполняющую систему и
возвращает число сформированных процессов
завершает исполняющую систему
вычисляет параметры оператора SnipHor
Заголовки функций и определения типов для их параметров находятся в файле inya.h.
2.6. Служебные функции диспетчера параллельных вычислений.
Заголовок функции
LOGPROC PE_GetNumProc();
void PE_SetProc( LOGPROC proc );
BOOL isEmptyProc( LOGPROC proc );
BOOL isEmpty();
PESTATE PE_GetState(
LOGPROC proc );
void PE_ExecProc( LOGPROC proc );
void PE_Exec();
void PE_WaitProc( LOGPROC proc );
void PE_Wait();
Описание
Возвращает количество логических процессов
Устанавливает индекс формируемого процесса
в proc
определяет, пуста ли очередь процесса proc
определяет, пусты ли все очереди
возвращает состояние процесса proc
выполняет одну итерацию главного цикла для
процесса proc
выполняет одну итерацию главного цикла
выполняет итерации главного цикла до момента
завершения процесса proc
запускает главный цикл диспетчера
Заголовки функций и определения типов для их параметров находятся в файле inya.h.
2.7. Функции формирования заданий и включения их в очереди процессов.
Вызов функции формирует задание и помещает его в очередь формируемого процесса.
Определения типов
typedef ULONG TMSADDR;
typedef void far *PCADDR;
typedef ULONG DATASIZE;
typedef int CALLPROC( void *)
// Адрес в памяти TMS320
// Адрес в памяти IBM PC
// Размер блока передаваемых данных (в словах TMS320 = 4 байта)
// PC процедура, выполняемая из очереди процесса
Заголовки интерфейсных функций и определения типов для их параметров находятся в файле
inya.h.
Èíÿ/Ñè. Îïèñàíèå ñèñòåìû. Âåðñèÿ îò 1/18/2016, ñòð. 11
PE_QRun()
Задание на загрузку исполняемого кода подчиненного модуля в ЛП и запуск его на выполнение.
Заголовок
void PE_QRun( const char *szFunName );
Параметры
szFunName - имя .out-файла подчиненного модуля.
PE_QPutDataAddr()
Задание на передачу блока памяти из ОП в ЛП.
Заголовок
void PE_QPutDataAddr( PCADDR source, TMSADDR dest, DATASIZE size );
Параметры
source - адрес начала блока источника передаваемых данных в ОП;
dest - адрес начала блока в ЛП, куда передаются данные;
size - размер блока передаваемых данных (в словах TMS320).
PE_QGetDataAddr()
Задание на передачу блока памяти из ЛП в ОП.
Заголовок
void PE_QGetDataAddr( TMSADDR source, PCADDR dest, DATASIZE size );
Параметры
source - адрес начала блока источника передаваемых данных в ЛП;
dest - адрес начала блока в ОП, куда передаются данные;
size - размер блока передаваемых данных (в словах TMS320).
PE_QPutValAddr()
Задание на передачу значения (4-байтового слова) из ОП в ЛП.
Заголовок
void PE_QPutValAddr( long int source, TMSADDR dest );
Параметры
source - передаваемое значение;
dest - адрес в ЛП, куда передается значение.
PE_QSect()
Задание на начало блока разделенного доступа.
Заголовок
void PE_QSect();
PE_QPost()
Задание на завершение блока разделенного доступа.
Èíÿ/Ñè. Îïèñàíèå ñèñòåìû. Âåðñèÿ îò 1/18/2016, ñòð. 12
Заголовок
void PE_QPost();
PE_QExec()
Задание на исполнение ЦП-выполняемой процедуры proc с блоком параметров data.
Заголовок
void PE_QExec( CALLPROC proc, void *data );
Параметры
proc - имя процедуры;
data - адрес в ОП блока данных процедуры.
Пример
typedef struct{ int handle;
// хэндлер файла
long pos;
// позиция в файле
void far *buffer;
// буфер данных
unsigned int count; } // длина данных
CALLREADDATA;
// блок параметров процедуры
int CallReadProc( void *data )
// исполняемая процедура
{ _lseek( (CALLREADDATA *)data->handle,
(CALLREADDATA *)data->pos, SEEK_SET );
_read( (CALLREADDATA *)data->handle,
(CALLREADDATA *)data->buffer,
(CALLREADDATA *)data->count );
free( data );
// освобождаем память блока данных
return 0; };
// интерфейсная функция
void QRead( int handle, long pos, void far *buffer, unsigned int count )
( CALLREADDATA *data = (CALLREADDATA *)malloc( sizeof( CALLREADDATA ) );
data->handle = handle;
data->pos = pos;
data->buffer = buffer;
data->count = count;
PE_QExec( CallReadProc, data ); );
2.8. Функции поддержки параллельных вычислений для программных модулей TMS320.
Заголовки функций и определения типов для их параметров находятся в файле _tms.h.
SetReady()
Функция сбрасывает признак занятости подчиненного процесса.
Заголовок
void SetReady();
Реализация
#define OUT_MEMORY 0x0809FF0
/* адрес блока памяти выходных параметров */
{ register unsigned long *PP = (unsigned long *)OUT_MEMORY;
*(PP + 15) = 0; }
ConvPCtoTMS()
Функция для преобразования чисел с плавающей точкой из формата IBM PC (IEEE) в формат TMS320.
Èíÿ/Ñè. Îïèñàíèå ñèñòåìû. Âåðñèÿ îò 1/18/2016, ñòð. 13
Заголовок
float ConvPCtoTMS( float valuePC );
Параметры
valuePC - число с плавающей запятой в 4-байтовом машинном формате IBM PC.
Возвращает
число с плавающей запятой в 4-байтовом машинном формате TMS320.
ConvTMStoPC()
Функция для преобразования чисел с плавающей точкой из формата TMS320 в формат IBM PC (IEEE).
Заголовок
float ConvTMStoPC( float valueTMS );
Параметры
valueTMS - число с плавающей запятой в 4-байтовом машинном формате TMS320.
Возвращает
число с плавающей запятой в 4-байтовом машинном формате IBM PC.
Раздел 3. Примеры.
3.1.Процедура parmmul - параллельное умножение матриц.
parmmul.сpp - исходный текст процедуры, распараллеливающей вычисления при произведении
матриц.
test1.сpp - исходный текст главной программы, демонстрирующей применение процедуры parmmul.
parmmul.cpp
#include <fstream.h>
#include <stdio.h>
#include <alloc.h>
#include <process.h>
#include <inya.h>
#include <math_tms.h>
void parmmul(
float *A,
/* 1-ая входная матрица */
long int I,
/* индекс 1-й входной матрицы */
float *B,
/* 2-ая входная матрица */
long int J,
/* индекс 2-й входной матрицы */
float *C,
/* выходная матрица */
long int K,
/* индекс выходной матрицы */
long int MC,
/* количество столбцов 1-й входной или выходной матрицы */
long int NC,
/* количество строк 2-й входной или выходной матрицы */
long int NA )
/* количество строк 1-й или столбцов 2-й входной матрицы */
{
// Инициация системы параллельных вычислений
int nProcesses = Init( 1, 8 )
// затребовано от 1 до 8 ПЭ
if( nProcesses == 0 )
{
// Выполняем, если были проблемы при инициации
printf( "Проблемы при инициации исполняющей системы Иня/Си.\n”
”Аварийное завершение задачи.\n" );
Èíÿ/Ñè. Îïèñàíèå ñèñòåìû. Âåðñèÿ îò 1/18/2016, ñòð. 14
Done
exit( 1 );
}
// Формируем параллельные процессы
ParDo( nProcesses, i )
SnipHor( NC, nOffset, nLenght );
// Вызываем интерфейсную функцию
mmul_tms( A, I,
B + nOffset * NA * J, J,
C + nOffset * MC * K, K,
MC, nLenght, NA );
ParEnd
// Ожидаем завершения процессов
Wait
Done
}
test1.cpp
#include <fstream.h>
#include <stdio.h>
#include <alloc.h>
#include <process.h>
/* Заголовок процедуры parmmul */
void parmmul( float *A, long int I, float *B, long int J, float *C, long int K, long int MC, long int NC, long int NA );
void main()
{
// ------------------------------- Вводим 1-ю матрицу ----------------------------------printf( "Введите количество столбцов и строк 1-й входной матрицы:\n" );
int nColumns1, nRows1;
scanf( “%u %u”, nColumns1, nRows1 );
// Выделяем память для 1-й входной матрицы
float *prMatrix1 = (float *)malloc( nColumns1 * nRows1 * 4 );
for( int j1 = 0; j1 < nRows1; j1++ )
{
printf( "Введите %i-ю строку 1-й матрицы:\n", j1 + 1 );
for( int i1 = 0; i1 < nColumns1; i1++ )
scanf( “%f ”, prMatrix1 + j1 * nColumns1 + i1 );
}
// ------------------------------- Вводим 2-ю матрицу ----------------------------------printf( "Введите количество столбцов и строк 2-й входной матрицы:\n" );
int nColumns2, nRows2;
scanf( “%u %u”, nColumns2, nRows2 );
if( nColumns1 != nRows2 )
{
printf( "Несовместимые размерности матриц.\nЗадача завершена.\n" );
free( prMatrix1 );
exit( 1 );
}
// Выделяем память для 2-й входной матрицы
float *prMatrix2 = (float *)malloc( nColumns2 * nRows2 * 4 );
for( int j2 = 0; j2 < nRows2; j2++ )
Èíÿ/Ñè. Îïèñàíèå ñèñòåìû. Âåðñèÿ îò 1/18/2016, ñòð. 15
{
printf( "Введите %i-ю строку 1-й матрицы:\n", j2 + 1 );
for( int i2 = 0; i2 < nColumns2; i2++ )
scanf( “%f ”, prMatrix2 + j2 * nColumns2 + i2 );
}
// Вызываем функцию parmmul
parmmul( prMatrix2, 1,
prMatrix1, 1,
prMatrix3, 1,
nColumns2, nColumns1, nRows1 );
ParEnd
// Ожидаем завершения процессов
Wait
// ------------------------------ Вывод результатов счета ----------------------------printf( "** Результирующая матрица ***************************************************\n\n" );
for( int j = 0; j < nRows1; j++ )
{
for( int i = 0; i < nColumns2; i++ )
printf( "%11e ", *( prMatrix3 + j * nColumns2 + i ) );
printf( "\n" );
}
printf( "*****************************************************************************\n\n" );
free( prMatrix1 );
free( prMatrix2 );
free( prMatrix3 );
}
3.2. Программа largmmul - параллельное умножение матриц,
не вмещающихся в оперативную память ПЭВМ.
В этом примере мы предполагаем, что 2-ая входная матрица целиком не помещается в
оперативную память ЦП и мы считываем ее с диска.
largmmul.сpp - исходный текст процедуры.
largmmul.cpp
#include <fstream.h>
#include <stdio.h>
#include <alloc.h>
#include <process.h>
#include "inya.h"
#include "math_tms.h"
// интерфейсная функция. См. описание примера в п. 2.7 (PE_QExec())
void QRead( int handle, long pos, void far *buffer, unsigned int count );
#define BUFLEN 4096
#define LEN_L sizeof( long )
long buffer[ BUFLEN ];
// длина буфера в длинных словах
// длина длинного слова в байтах
// буфер чтения ограниченной длины
// Интерфейсная функция поблочного чтения данных из файла и передача их в TMS
void QBlockRead( void far *buffer, int nBufLen, int handle, long pos, TMSADDR dest, DATASIZE size )
{ Sect // начало критической программной области
for( int i = 0; i < count / nBufLen; i++ )
{ QRead( handle, pos + i * BUFLEN * LEN_L, buffer, BUFLEN * LEN_L );
PE_QPutDataAddr( buffer, dest + i * BUFLEN, BUFLEN ); }
QRead( handle, pos + i * BUFLEN * LEN_L, buffer, ( count % BUFLEN ) * LEN_L ) );
PE_QPutDataAddr( buffer, dest + i * BUFLEN, count % BUFLEN );
Post } // окончание критической программной области
Èíÿ/Ñè. Îïèñàíèå ñèñòåìû. Âåðñèÿ îò 1/18/2016, ñòð. 16
void largmmul( float *A,
/* 1-ая входная матрица */
long int I,
/* индекс 1-й входной матрицы */
const char *szFName, /* имя файла, содержащего 2-ую входную матрицу */
long int J,
/* индекс 2-й входной матрицы */
float *C,
/* выходная матрица */
long int K,
/* индекс выходной матрицы */
long int MC,
/* количество столбцов 1-й входной или выходной матрицы */
long int NC,
/* количество строк 2-й входной или выходной матрицы */
long int NA )
/* количество строк 1-й или столбцов 2-й входной матрицы */
{
// Инициация системы параллельных вычислений
int nProcesses = Init( 1, 8 )
// затребовано от 1 до 8 ПЭ
if( nProcesses == 0 )
{
// Выполняем, если были проблемы при инициации
printf( "Проблемы при инициации исполняющей системы Иня/Си.\n”
”Аварийное завершение задачи.\n" );
Done
exit( 1 );
}
// Открываем файл с 2-й входной матрицей
int fh = _open( szFName, _O_RDONLY );
if( fh == -1 )
// если были проблемы при открытии файла
{
printf( “Проблемы при открытии файла %s.\n”
”Аварийное завершение задачи.\n”, szFName );
Done
exit( 2 );
}
// Формируем параллельные процессы
ParDo( nProcesses, i )
SnipHor( NC, nOfs, nLen );
mmul_tms( A, I,
B + nOffset * NA * J, J,
C + nOffset * MC * K, K,
MC, nLenght, NA );
// Вместо вызова интерфейсной функции мы переносим ее текст целиком и затем модифицируем
/* Задания на загрузку исходных данных в ЛП */
PE_QPutDataAddr( A, TMSADDR_MMUL_A, I * MC * NA );
PE_QPutValAddr( I, TMSADDR_MMUL_I );
QBlockRead( buffer, BUFLEN, fh, J * NA * nOfs, TMSADDR_MMUL_B, J * NA * nLen );
PE_QPutValAddr( J, TMSADDR_MMUL_J );
PE_QPutValAddr( K, TMSADDR_MMUL_K );
PE_QPutValAddr( MC, TMSADDR_MMUL_MC );
PE_QPutValAddr( nLenght, TMSADDR_MMUL_NC );
PE_QPutValAddr( NA, TMSADDR_MMUL_NA );
/* Задание на загрузку исполняемого кода модуля в ЛП и запуска его на выполнение */
PE_QRun( "_mmul.out" );
/* Задание на считывание данных результата выполнения в ОП */
PE_QGetDataAddr( TMSADDR_MMUL_C, C + K * MC * nOfs, K * MC * nLen );
ParEnd
// Ожидаем завершения процессов
Wait
_close( fh );
Done
}
Èíÿ/Ñè. Îïèñàíèå ñèñòåìû. Âåðñèÿ îò 1/18/2016, ñòð. 17
3.3.Реализация подчиненного программных модуля mmul.
_mmul.с - исходный текст подчиненного программного модуля, вычисляющего произведение
матриц;
_mmul.bat - командный файл MS DOS для трансляции модуля _mmul.с;
_mmul.cmd - командный файл компоновщика для модуля _mmul.c;
_mmul.map - файл листинга компоновщика после обработки модуля _mmul.
math_tms.h - файл определений интерфейсных математических функций.
_mmul.c
/*---------------------------------------------------------------------------------------------------------------Модуль, вычисляющий произведение матриц A и B и помещающий результат в C.
----------------------------------------------------------------------------------------------------------------*/
#include "_tms.h"
#define MLENGHT 1000
long int A[ MLENGHT ];
int I;
long int B[ MLENGHT ];
int J;
long int C[ MLENGHT ];
int K;
int MC;
int NC;
int NA;
/* максимальное количество элементов матрицы */
/* first input matrix
/* A's index
/* second input matrix
/* B's index
/* output matrix
/* C's index
/* C's column number ( A's column number )
/* C's row
number ( B's row number )
/* A's row
number ( B's column number )
main()
{
register int i, r, p, q;
/* Конвертируем массив A из формата PC в формат TMS320 */
for( i = 0; i < MC * NA; i += I )
A[ i ] = ConvPCtoTMS( A[ i ] );
/* Конвертируем массив B из формата PC в формат TMS320 */
for( i = 0; i < NC * NA; i += J )
B[ i ] = ConvPCtoTMS( B[ i ] );
/* Обнуляем выходной массив */
for( i = 0; i < MC * NC; i += K )
C[ i ] = 0;
/* Вычисляем произведение матриц */
for( r = 0; r <= NA - 1; r++ )
for( p = 0; p <= MC - 1; p++ )
for( q = 0; q <= NC - 1; q++ )
C[ ( p + q * MC ) * K ] += A[ ( p + r * MC ) * I ] * B[ ( r + q * NA ) * J ];
/* Обратная конверсия массива C из формата TMS320 в формат PC */
for( i = 0; i < MC * NC; i += K )
C[ i ] = ConvTMStoPC ( C[ i ] );
/* Сбрасываем признак занятости */
SetReady();
}
*/
*/
*/
*/
*/
*/
*/
*/
*/
Èíÿ/Ñè. Îïèñàíèå ñèñòåìû. Âåðñèÿ îò 1/18/2016, ñòð. 18
_mmul.bat
:: Командная файл для трансляции файла _mmul.c
::
:: Параметры коммандной строки транслятора:
::
-o - ключ глобальной оптимизации кода
::
-iinclude - путь к каталогу “include” .h-файлов include
::
_mmul - имя .c-файла исходного текста модуля
::
-z - далее идут параметры компоновщика:
::
-ilib - путь к каталогу “lib” библиотек объектных модулей
::
-m_mmul.map - имя файла “_mmul.map” листинга компоновщика
::
-o_mmul.out - имя .out-файла (объектного файла подчиненного модуля)
::
_mmul.cmd - имя командного файла компоновщика
::
cl30 -o -s -iinclude _mmul -z -ilib -m_mmul.map -o_mmul.out _mmul.cmd
::
:: Параметры коммандной строки конвертора .MAP - .H файл:
::
_mmul.map - имя файла листинга компоновщика
::
math_tms.h - имя .H файла, содержащего адреса глобальных переменных модуля
::
TMSADDR_MMUL_ - префикс символических имен адресов глобальных переменных
::
maph30 _mmul.map math_tms.h TMSADDR_MMUL_
_mmul.cmd
/*---------------------------------------------------------------------------------------------------------------Командный файл для компоновки модуля _mmul.c
----------------------------------------------------------------------------------------------------------------*/
-c
/* компонуем, используя стандартные соглашения C */
-lrts.lib
/* подключаем библиотеку времени выполнения
*/
/* Области данных модуля процессора TMS320 */
MEMORY
{
RAM3:
org = 0x010000, len = 0x3F0000 /* область памяти программных модулей */
RAMP:
org = 0x809800, len = 0x7C0
/* область быстрой памяти
*/
}
/* Задаем размещение секций программного модуля в локальной памяти */
SECTIONS
{
.text: {} > RAMP
/* исполняемый код
.cinit: {} > RAMP
/* таблицы инициализированных переменных
.data: {} > RAMP
/* данные
.bss:
{} > RAM3
/* глобальные и статические переменные
.stack: {} > RAM3
/* системный стек
}
_mmul.map
ЗАМЕЧАНИЕ: Приводится только часть файла листинга.
*****************************************************
TMS320C30 Linker
Version 4.10
*****************************************************
...
GLOBAL SYMBOLS
address
name
--------------...
00010000 _A
000103e8 _B
000107d0 _C
address
----------
name
------
*/
*/
*/
*/
*/
Èíÿ/Ñè. Îïèñàíèå ñèñòåìû. Âåðñèÿ îò 1/18/2016, ñòð. 19
00010bb8 _I
00010bb9 _J
00010bba _K
00010bbb _MC
00010bbc _NA
00010bbd _NC
...
math_tms.h
ЗАМЕЧАНИЕ: Приводится только часть файла.
/*---------------------------------------------------------------------------------------------------------------Интерфейсные функции (см. п. п. 1.2 и 1.3 Описания системы),
доступные в главном (PC) программном модуле.
----------------------------------------------------------------------------------------------------------------*/
...
/*---------------------------------------------------------------------------------------------------------------Интерфейсная функция модуля _mmul.out
----------------------------------------------------------------------------------------------------------------*/
/* (!) Сравните с значениями из файла _mmul.map листинга компоновщика */
#define TMSADDR_MMUL_A 0x00010000
#define TMSADDR_MMUL_B 0x000103e8
#define TMSADDR_MMUL_C 0x000107d0
#define TMSADDR_MMUL_I 0x00010bb8
#define TMSADDR_MMUL_J 0x00010bb9
#define TMSADDR_MMUL_K 0x00010bba
#define TMSADDR_MMUL_MC 0x00010bbb
#define TMSADDR_MMUL_NA 0x00010bbc
#define TMSADDR_MMUL_NC 0x00010bbd
void mmul_tms(
float *A,
/* first input matrix */
long int I,
/* A's index */
float int *B,
/* second input matrix */
long int J,
/* B's index */
float int *C,
/* output matrix */
long int K,
/* C's index */
long int MC,
/* C's column number ( A's column number ) */
long int NC,
/* C's row
number ( B's row
number ) */
long int NA )
/* A's row
number ( B's column number ) */
{
/* Задания на загрузку исходных данных в ЛП */
PE_QPutDataAddr( A, TMSADDR_MMUL_A, I * MC * NA );
PE_QPutValAddr( I, TMSADDR_MMUL_I );
PE_QPutDataAddr( B, TMSADDR_MMUL_B, J * NA * NC );
PE_QPutValAddr( J, TMSADDR_MMUL_J );
PE_QPutValAddr( K, TMSADDR_MMUL_K );
PE_QPutValAddr( MC, TMSADDR_MMUL_MC );
PE_QPutValAddr( NC, TMSADDR_MMUL_NC );
PE_QPutValAddr( NA, TMSADDR_MMUL_NA );
/* Задание на загрузку исполняемого кода модуля в ЛП и запуска его на выполнение */
PE_QRun( "_mmul.out" );
/* Задание на считывание данных результата выполнения в ОП */
PE_QGetDataAddr( TMSADDR_MMUL_C, C, K * MC * NC );
}
...
Èíÿ/Ñè. Îïèñàíèå ñèñòåìû. Âåðñèÿ îò 1/18/2016, ñòð. 20
Список литературы.
1. Third-Generation TMS320 User`s Guide. - Texas Instruments, 1989.
В руководстве описываются принципы организации и основные характеристики третьего поколения
процессоров семейства TMS320.
2. Анисимов В.А., Малышкин В.Э., Миренков Н.Н. Язык параллельного программирования для
крупноблочных МВК. - (Препринт #824, 29 с.; #825, 27 с. ВЦ, АН СССР, Сиб. отд-е) Новосибирск, 1989.
Работа описывает архитектуру многопроцессорных вычислительных комплексов, описание и
технологию программирования в языке “Иня”, рассматриваются понятия одновременно протекающих
систем процессов, описываются языковые средства для их задания, синхронизации и обменов. Вторая
часть работы (препринт #825) описывает независимо протекающие процессы и средства увеличения
эффективности вычислений.
3. Хоар. Ч. Взаимодействующие последовательные процессы: Пер. с англ. - М.: Мир, 1989.
Классическая работа по теории параллельных вычислений.
4. Керниган Б., Ритчи Д. Язык программирования Си. 2-е изд., перераб. и доп.: Пер. с англ. - М.:
Финансы и статистика, 1992. - 272 с.
Описание
версии
языка
Си,
принятой
в
качестве
стандарта
Американским
Институтом
Национальных Стандартов (ANSI).
5. Эллис М., Строуструп Б. Справочное руководство по языку программирования С++ с
комментариями. Проект стандарта ANSI: Пер. с англ. - М.: Мир, 1992.
Подробное описание языка Си++, предлагающееся в качестве проекта стандарта ANSI.
6. APEX Reference Manual, Release 80.1, D.3. - FPS Technical Publications Staff, Portland, 1982.
Описание функций Диспетчера Матричных Процессоров (APEX) фирмы Floating Point Systems.
Related documents
Download