♦
Считается, что фундаментальные подходы управления процессом вычислений
пото́ком данных (DATA-FLOW) в противове́с программному управлению
(CONTROL-FLOW) предложил на рубеже 70-х г.г.
Джек Деннис
(Jack Dennis).
Графическую модель пото́ковых (управляемых данными) вычислений обосновад
в своей докторской диссертационной работе сотрудник Стэнфордского университета
Дуайн Адамс
(Duane Adams) в 1968 г.
DATA-FLOW вычислительное устройство имеет кольцевую структуру; машинные инструкции и данные
с признаками (то́кены) хранятся в единой сверхбыстродействующей ассоциативной памяти (АП),
готовые к исполнению (ГКВ) по условию готовности их операндов инструкции с помощью
входного коммутатора K1 выбираются из АП и передаются
исполняющим устройствам (ИУ); результат выполнения оператора с помощью выходного коммутатора
K2 записывается в АП и определяет готовность очередных операндов (а через них - и операторов).
Т.о. рандеву́ команд и данных реализуется на исполняющих устройствах.
ИУ могут быть арифметическими (АИУ) - выполняющими арифметические действия
(кстати, поле АИУ не обязательно должно
быть гомогенным - вычислительные возможности каждого могут различаться),
служить для связи с внешними устройствами и др. Важно учесть, что режим выполнения
параллельных частей программ в вычислителях DATA-FLOW является асинхронным (фактические
каждое ИУ работает в своём временно́м режиме).
На фрагменте а) рисунка слева показано
"облако операторов"
(неструктурированный список операторов с
указа́нием необходимых для выполнения каждого опера́ндов)
согласно вышеприведённому преобразованию. В данном случае "облако" включает 3 оператора
- a×b, a/c и a×b+a/c (последнее выражение здесь и далее
означа́ет единственный оператор "сложе́ние"), причём порядок
выполнения операторов не определён.
Преобразование графа алгоритма к ЯПФ может быть вы́полнено вручную
(при числе операторов порядка нескольких десятков), програ́ммным путем
или с использованием вычислительных систем специальной архитектуры -
пото́ковых (DATA-FLOW) вычислителей (уже на аппаратном уровне).
Компьютерный симулятор позволяет выполнять счётные программы
в стиле DATA-FLOW, обладает ра́звитой системой протоколирования работы, даёт
возможность вести статистику работы отдельных элементов вычислителя (при учёте
относительного времени выполнения отдельных инструкций), определять
величину интенсивности вычислений - функцию
числа параллельно выполняющихся операций по ходу решения задачи и др.
(данные выводятся в файлы заданного формата с целью последующего импорта для
анализа сторо́нними программами - например, построе́ния графики в MS Excel).
Видно, что характер функции I(t) неизменен
для конкретного алгоритма, величина же э́кстремума интенсивности
вычислений пропорциональна квадрату разме́рности данных.
...Интересно, почему так? Особенно если вспомнить, что функция
вычислительной сложности алгоритма умножения матриц принадлежит классу O(N3) ...
Что-то характер полученных кривых напоминает
функцию
вероятности распределения Пуассона с небольшим математическим ожиданием...
Уж не является процесс вычислений (как минимум в данном случае) одним из вариантов
процессов массового обслуживания?..
Пример графика обобщённой функции динамической вычислительной
сложности приведен на рис. справа, где число выполненных операций N показано в функции как
размера обрабатываемых данных n, так и времени t процесса вычислений.
На самом деле, конечно, параметры n и t не являются, строго говоря,
ортогональными вследствие явно просле́живаемой зависимости t(n); однако правомо́чность
рассмотре́ния и анализа зависимости N(n,t) заключается в я́вном указа́нии
формы кумулятивной кривой вы́полненных операций.
Т.о. сре́зы функции N(n,t) при t=const представляют собой
классическую функцию вычсложности, сре́зы при n=const представляют собой нако́пленные
(кумулятивные) функции числа вы́полненных операций (интеграл функции
интенсивности вычислений).
Видно, что и в этом случае неравномерность функции интенсивности вычислений I(t)
по времени остаётся значительной.
Так что разработка методов её целенапра́вленного изменения
остаётся заманчивым делом!
Логично, например, ввести критерий "полезности" ("перcпективности") каждого оператора
с точки зрения выполнения коне́чной цели - скоре́йшего завершения программы (напр.,
предположить, что "полезность" оператора зависит от количества иных операторов, которым данный
обеспечивает готовность их входных операндов).
При таком подходе в простейшем случае для оператора i его "перспективность" Pi
определяется числом операторов j, выполнение ко́их зависит (по операндам) от исполнения данного,
тогда Pi=j. Если учитывать вес каждого (из общего числа nj ; обычно
nj=1÷2, но в общем случае может быть любым) входного операнда, получаем
Pi=∑(1/nj) и т.д. Де́йственность каждого метода
возможно проверить путём компьютерного моделирования процесса вычислений на DATA-FLOW машине.
В новой версии симулятора DATA-FLOW вычислителя предусмотрена возможность моделирования
различных стратегий управления интенсивностью вычислений.
Результаты компьютерного моделирования стратегий управления интенсивностью вычислений
приведены на рисунке справа (на примере решения СЛАУ 5-го порядка). При единичном арифметическом исполняющем
устройстве (АИУ) имеем чисто последовательный вычислитель, при числе АИУ более 24 (максимальное число
ГКВ-операций для данного алгоритма) полностью реализуется потенциал распараллеливания (пятикратное ускорение
вычислений).
Летом 2022 г. (Крым,
Щёлкино
& Чокрак)
создана версия (ver. 4.6) симулятора DATA-FLOW вычислителя
с использованием предика́тов с целью управления последовательностью вычислений.
Автор убеждён, что предика́тное выполнение операций - наилучшее решение для потоко́вого
(DATA-FLOW) вычислителя, ибо идеально соответствует основной идеологе́ме указанной о́ного архитектуры
- "правильным образом организованные ДАННЫЕ управляют ПОСЛЕДОВАТЕЛЬНОСТЬЮ ИХ ОБРАБОТКИ";
см. инсталляционный файл INSTALL_DF.EXE
(размер 2,7 Mбайт, Win'32, GUI; вариант гомогенного поля АИУ) +
руководство Исследователя.
Формат команды с использованием предиката приведён ниже
(квадратные скобки означают необязательность заключённого в них текста) :
Нижеприведён пример использования этого подхода для нахожде́ния ВСЕХ (как
вещественных, так и мнимых) корней полного квадратного уравнения (представлен текст
соответствующей программы):
Второй пример - поиск максимума элементов массива чисел (длиной 8 элементов)
методом последовательного сравне́ния (по двойкам чисел) для выявления экстремумов
(аналогично проводится суммирование, умножение etc -
ассоциативные операции):
♦
♦
♦
♦
♦
♦
♦
♦
В DATA-FLOW вычислителях
реализованы правила обработки токенов, позволяющие реализовать многократное выполнение
последовательности инструкций (т.е. организовывать циклы, переходы). Потоковые системы
фактически реализуют принцип управления событиями на аппаратном уровне - каждый акт выполнения
оператора на ИУ инициирует определе́ние нового списка ГКВ-инструкций, которые запускаются
на исполнение на свободных ИУ.
На фрагменте б) приведён вариант последовательного
выполнения операторов - сначала выполняются a×b и a/c
(в любой последовательности), далее вычисляется конечный результат
преобразования в виде r=a×b+a/c.
Фрагмент в) иллюстрирует параллельное вычисление - операторы
a×b и a/c выполняются одновременно (ибо не
зависят друг от друга по операндам), далее выполняется
зависящий по операндам от их выполнения оператор
a×b+a/c.
Под "зави́симостью по операндам" понимается явление
невозможности выполнения оператора, все (или часть) операндов которого
являются результатом выполнения других операторов (пока они не исполнятся,
данный оператор вы́полнен быть не может). Часто говорят, что выполнение
такого оператора "откла́дывается" (естественно, до момента, когда все его
операнды будут "готовы").
Для наглядности операторы, независимые друг от друга по операндам, располагаются
на схеме на одном уровне (я́русе), как показано на фрагменте в).
Если время выполнения рассмотренных операторов
ta×b ,
ta/c и
ta×b+a/c соответственно,
то время выполнения последовательного варианта суть
tпосл. = ta×b +
ta/c + ta×b+a/c , а параллельного -
tпар. = max(ta×b , ta/c) + ta×b+a/c
(если не учитывать временны́е задержки при передаче данных между вычислительными устройствами).
В случае ta×b = ta/c = ta×b+a/c
получаем вы́игрыш по времени вычислений в 1,5 раза.
С целью выявле́ния потенциала распараллеливания алгоритма его
граф удобно предста́вить в ЯПФ; при этом из общего множества операторов выделяются
группы (обычно представля́емые в виде я́русов), зави́симые (по операндам)
только от результов выполнения операторов иного, предыдущего, яруса (на схеме слева отдельные
я́русы расположены вертикально). Если число параллельно работающих исполнительных устройств ограничено,
часть операторов может быть перенесено на более нижние ярусы; при этом время
выполнения программы увеличится.
На данное программное обеспечение получено (совместно с аспирантом Ханжиным Д.А.)
СВИДЕТЕЛЬСТВО о государственной регистрации
программ для ЭВМ № 2013614155
(Федеральная служба по интеллектуальной
собственности Российской Федерации - Роспатент,
заявка № 2013610527, дата поступления 24.I.2013 г.,
зарегистрировано в Реестре программ для ЭВМ 24.IV.2013 г.).
Бросается в глаза явно вы́раженная неравноме́рность
(арбитра́ж "готовых к исполнению" операций не производился)
функции интенсивности вычислений
I(t); пунктиром показана некоторым
о́бразом усреднённая зависимость I(t).
Показанные на рис. справа неравномерности ("шква́лы"
интенсивности вычислений) объясняются собственно принципами работы пото́кового
вычислителя - сле́дствием выполнения на ИУ каждого
оператора является устано́вка в состояние готовности множества входных операндов
иных операторов, для которых результат выполнения данного является входным
операндом.
Подобная неравномерность не сули́т ничего хорошего -
ведь её следствием является не менее вы́раженная неравномерная нагрузка на шины передачи данных
(в первую очередь входного коммутатора, да и
выходного тоже)... а это как раз
самые слабые места пото́ковых вычислительных
структур - именно тут и начинаются всяческие неприятные вещи -
аппаратные го́нки и т.п. штуки...
что делать - это один из (известных) недостатков SMP-подобной архитектуры!
Классическим методом снижения нагрузки на шины данных
SMP-вычислителя является принудительная (обычно небольшая сравнительно с
характе́рным временем выполнения машинных инструкций) задержка в
моментах начала передачи данных; при этом неизбежно возрастание общего
времени выполнения программы (компенсируемое, впрочем, возможностью
заде́йствования бо́льшего количества ИУ). При этом
приобретает значение порядок за́пуска на исполнение команд,
с помощью которого можно управлять интенсивностью вычислений.
Обозначения на рисунке: 1 - равноприоритетное выполнение ГКВ-инструкций, 2 - режим
интенсификации, 3 - депрессивный режим.
Зависимости 2 и 3 соответственно иллюстрируют применению одной из стратегий управления ИВ c целью
интенсификации процесса вычислений и его депрессии (по сравнению с равноприоритетной вы́боркой
ГКВ-инструкций из буфера - линия 1).
Режимы интенсификации и депрессии в процессе вычислений, естественно,
могут целенаправленно перемежа́ться; при значительном количестве операций в алгоритме эффективность
подобного управления возрастает.
Итак, обоснована и доказана на уровне математического моделирования
и компьютерной симуляции возможность целенаправленного управления интенсивностью вычислений
в процессорах пото́ковой архитектуры, что даёт возможность, в частности,
"разру́ливать" узкие места DATA-FLOW вычислителя (регулировать трафик внутрикристальных
шин обмена данными, минимизируя последствия его "шква́листого" характера).
;
'
означает комментарий до конца строки):
; Решение полного квадратного уравнения в вещественных числах A×X2 + B×X + C = 0
; а́вторство - великий индийский астроном и математик БРАХМАГУПТА (7-й век н.э.)
;
; in case A = 1, B = 7, C = 3 the solve is: X1 = -0.45862 , X2 = -6.5414
; файл SQUA_EQU_2.SET
;
MUL A, TWO, A2 ; А2 ← 2 × A
MUL A, FOUR, A4 ; A4 ← 4 × A
MUL B, NEG_ONE, B_NEG ; B_NEG ← NEG_ONE × B
POW B, TWO, BB ; BB ← B2
MUL A4, C, AC4 ; AC4 ← A4 × C
SUB BB, AC4, D ; D[iskriminant] ← BB - AC4
SQR D, sqrt_D ; sqrt_D ← sqrt(D)
;
ADD B_NEG, sqrt_D, W1 ; W1 ← B_NEG + sqrt_D
SUB B_NEG, sqrt_D, W2 ; W2 ← B_NEG - sqrt_D
DIV W1, A2, X1 ; X1 ← W1/A2
DIV W2, A2, X2 ; X2 ← W2/A2
;
SET 1.0, A ; A ← 1.0
SET 7.0, B ; B ← 7.0
SET 3.0, C ; C ← 3.0
;
SET 2, TWO ; TWO ← 2
SET 4, FOUR ; FOUR ← 4
;
SET -1, NEG_ONE ; NEG_ONE ← (-1)
Формально введены́ бина́рные флаги, управляющие выполнением
(или наоборот) каждой арифметико-логической операцией (аналогично
архитектуры IA-64)
и реализованы (двуме́стные) операции над предикатами
(конъюнкция, дизъюнкция, импликация, эквивале́нция);
более сложные операции над предикатами предполагается выполнять последовательно в идеологе́ме двуме́стного синтаксиса.
Важным преимуществом предикатного подхода управления последовательностью
выполнения операций является отсутствие инструкций безусловного и условного переходов в коде
программы, что кардинально упрощает анализ и оптимизацию программ в форме информационного графа алгоритма.
Благодаря добавления флага-предиката в виде последнего в списке параметров
операции достигается полная совместимость с прежней системой команд - при отсутствии предиката
он (по умолчанию) считается true
.
На данное программное обеспечение получено
СВИДЕТЕЛЬСТВО о государственной регистрации
программ для ЭВМ № 2018665726
(Федеральная служба по интеллектуальной
собственности Российской Федерации - Роспатент,
заявка № 2018662732, дата поступления 13.X.2018 г.,
зарегистрировано в Реестре программ для ЭВМ 10.XII.2018 г.).
ADD Op1 [, Op2], Res [?|, Pred] [; комментарий до конца строки]
где
ADD
– мнемоника команды (здесь - сложение), Оp1
и Оp2
– аргументы команды, Res
– результат
выполнения команды, Pred
– необязательное имя предиката,
символом-разделителем перед полем предиката могут служить ‘?’ или ‘,’,
перед именем предиката допускается символ отрицания ‘!’.
; Нахожде́ние корней полного квадратного уравнения A×X2 + B×X + C = 0
; для получения решения в комплексных числах используем флаг предиката
; флаг IS_re есть true при значении дискриминанта D>=0 (вещественные корни) и наоборот
; in case A = 1, B = 7, C = 3 the solve is: re_X1=-0.459, im_X1=0; re_X2=-6.541, im_X2=0
; in case A = 1, B = 3, C = 3 the solve is: re_X1=-1.5, im_X1=0.866; re_X2=-1.5, im_X2=-0.866
;
; файл SQUA_EQU_2.PRED.SET
;
MUL A, TWO, A2 ; А2 ← 2 × A
MUL A, FOUR, A4 ; A4 ← 4 × A
MUL B, NEG_ONE, B_NEG ; B_NEG ← NEG_ONE × B
POW B, TWO, BB ; BB ← B2
MUL A4, C, AC4 ; AC4 ← A4 × C
SUB BB, AC4, D ; D[iskriminant] ← BB - AC4
;
SQR D, sqrt_D ? IS_re ; sqrt_D ← sqrt(D)
ADD B_NEG, sqrt_D, W1 ? IS_re ; W1 ← B_NEG + D_SQRT
SUB B_NEG, sqrt_D, W2 ? IS_re ; w2 ← B_NEG - D_SQRT
DIV W1, A2, re_X1 ? IS_re ; re_X1 ← W1 / A2
DIV W2, A2, re_X2 ? IS_re ; re_X2 ← W2 / A2
;
MUL D, NEG_ONE, NEG_D ? !IS_re ; NEG_D ← NEG_ONE × D
SQR NEG_D, sqrt_D ? !IS_re ; sqrt_D ← sqrt(NEG_D)
DIV B_NEG, A2, re_X1 ? !IS_re ; re_X1 ← B_Neg / A2
DIV sqrt_D, A2, im_X1 ? !IS_re ; im_X1 ← sqrt_D / A2
CPY re_X1, re_X2 ? !IS_re ; re_X2 ← re_X1
DIV sqrt_D, A2, W ? !IS_re ; W ← sqrt_D / A2
MUL W, NEG_ONE, im_X2 ? !IS_re ; im_X2 ← W × NEG_ONE
;
SET 1, A ; A ← 1
SET 3, B ; B ← 3/(7)
SET 3, C ; C ← 3
;
SET 2, TWO ; TWO ← 2
SET 4, FOUR ; FOUR ← 4
SET -1, NEG_ONE ; NEG_ONE ← (-1)
;
SET 0,ZERO
;
PGE D,ZERO, IS_re ; IS_re ← true if D>=0
Третий пример - поиск максимумума элементов массива чисел (длиной 8 элементов)
методом сдва́ивания
(аналогично проводится суммирование, умножение etc -
ассоциативные операции):
; Поиск максимума в массиве с использование предикатов
; используется алгоритм последовательного сравнения чисел в массиве
;
; файл MAX-1_MASS-8.PRED.SET
;
SET 3, m01 ; первый элемент массива
SET 5, m02
SET 2, m03
SET 111, m04
SET 13, m05
SET 9, m06
SET 2, m07
SET 6, m08 ; последний элемент массива
;
PGE m02, m01 ? IS_02_ge_01 ; IS_02_ge_01 -> true if m02>=m01
CPY m02, max_01-02 ? IS_02_ge_01 ; if m02 >= m01
CPY m01, max_01-02 ? !IS_02_ge_01 ; if m02 < m01
;
PGE m03, max_01-02 ? IS_03_ge_max_01-02 ; IS_03_ge_max_01-02 -> true if m03>=max_01-02
CPY m03, max_01-03 ? IS_03_ge_max_01-02 ; if m03 >= max_01-02
CPY max_01-02, max_01-03 ? !IS_03_ge_max_01-02 ; if m03 < max_01-02
;
PGE m04, max_01-03 ? IS_04_ge_max_01-03 ; IS_04_ge_max_01-03 -> true if m04>=max_01-03
CPY m04, max_01-04 ? IS_04_ge_max_01-03 ; if m04 >= max_01-03
CPY max_01-03, max_01-04 ? !IS_04_ge_max_01-03 ; if m04 < max_01-03
;
PGE m05, max_01-04 ? IS_05_ge_max_01-04 ; IS_05_ge_max_01-04 -> true if m05>=max_01-04
CPY m05, max_01-05 ? IS_05_ge_max_01-04 ; if m05 >= max_01-04
CPY max_01-04, max_01-05 ? !IS_05_ge_max_01-04 ; if m05 < max_01-04
;
PGE m06, max_01-05 ? IS_06_ge_max_01-05 ; IS_06_ge_max_01-05 -> true if m06>=max_01-05
CPY m06, max_01-06 ? IS_06_ge_max_01-05 ; if m06 >= max_01-05
CPY max_01-05, max_01-06 ? !IS_06_ge_max_01-05 ; if m06 < max_01-05
;
PGE m07, max_01-06 ? IS_07_ge_max_01-06 ; IS_07_ge_max_01-06 -> true if m07>=max_01-06
CPY m07, max_01-07 ? IS_07_ge_max_01-06 ; if m07 >= max_01-06
CPY max_01-06, max_01-07 ? !IS_07_ge_max_01-06 ; if m07 < max_01-06
;
PGE m08, max_01-07 ? IS_08_ge_max_01-07 ; IS_08_ge_max_01-07 -> true if m08>=max_01-07
CPY m08, max_01-08 ? IS_08_ge_max_01-07 ; if m08 >= max_01-07 / решение - max_01-08
CPY max_01-07, max_01-08 ? !IS_08_ge_max_01-07 ; if m08 < max_01-07 / решение - max_01-08
; Поиск максимума в массиве с использование предикатов
; используется алгоритм сдва́ивания
;
; файл MAX-2_MASS-8.PRED.SET
;
SET 3, m01 ; первый элемент массива
SET 5, m02
SET 17, m03
SET 234, m04
SET 13, m05
SET 9, m06
SET 2, m07
SET 6, m08 ; последний элемент массива
;
; первый этап сравнения
;
PGE m02, m01 ? IS_02_ge_01 ; IS_02_ge_01 ← true if m02 >= m01
CPY m02, max_01-02 ? IS_02_ge_01 ; if m02 >= m01
CPY m01, max_01-02 ? !IS_02_ge_01 ; if m02 < m01
;
PGE m04, m03 ? IS_04_ge_03 ; IS_04_ge_03 ← true if m04 >= m03
CPY m04, max_03-04 ? IS_04_ge_03
CPY m03, max_03-04 ? !IS_04_ge_03
;
PGE m06, m05 ? IS_06_ge_05 ; IS_06_ge_05 ← true if m06 >= m05
CPY m06, max_05-06 ? IS_06_ge_05
CPY m05, max_05-06 ? !IS_06_ge_05
;
PGE m08, m07 ? IS_08_ge_07 ; IS_08_ge_07 ← true if m08 >= m07
CPY m08, max_07-08 ? IS_08_ge_07
CPY m07, max_07-08 ? !IS_08_ge_07
;
; второй этап сравнения
;
PGE max_03-04, max_01-02 ? IS_0304_ge_0102
CPY max_03-04, max_01-04 ? IS_0304_ge_0102
CPY max_01-02, max_01-04 ? !IS_0304_ge_0102
;
PGE max_07-08, max_05-06 ? IS_0708_ge_0506
CPY max_07-08, max_05-08 ? IS_0708_ge_0506
CPY max_05-06, max_05-08 ? !IS_0708_ge_0506
;
; третий этап сравнения
;
PGE max_05-08, max_01-04 ? IS_0508_ge_0104
CPY max_05-08, max_01-08 ? IS_0508_ge_0104 ; решение - max_01-08
CPY max_01-04, max_01-08 ? !IS_0508_ge_0104 ; решение - max_01-08
♦
♦
♦
♦
♦
♦