История исследований в области
ПОТО́КОВЫХ (DATA-FLOW) вычислителей

  1. Внимание! Мы начинаем АНАЛИЗИРОВАТЬ АЛГОРИТМЫ (точнее, изучать их СТРУКТУРУ, СВОЙСТВА и ОСОБЕННОСТИ РЕАЛИЗАЦИИ, в первую очередь в части их скры́того параллелизма)... )... Очень рекомедуется посещение сайта AlgoWiki.ru... очень рекомендуется сначала (а можно как "в процессе", так и "опосля́") поработать (или хотя бы ознакомиться) c ресурсом AlgoWiki - открытой энциклопедией по свойствам алгоритмов и особенностям их реализации на различных программно-аппаратных платформах (от мобильных платформ до экзафлопсных суперкомпьютерных систем) с возможностью коллективной работы всего мирового вычислительного сообщества.

    Тематические публикации по теме на HABR'е:

    Есть ли параллелизм в произвольном алгоритме и как его использовать лучшим образом (https://habr.com/ru/post/530078/, 26.11.2020)
    Такие важные короткоживущие данные (https://habr.com/ru/post/534722/, 24.12.2020)
    Это непростое условное выполнение (https://habr.com/ru/post/535926/, 03.01.2021)
    Динамика потокового вычислителя (https://habr.com/ru/post/540122/, 01.02.2021)
    Параллелизм и плотность кода (https://habr.com/ru/post/545498/, 05.03.2021)
    Сколько стоит расписание (https://habr.com/ru/post/551688/, 10.04.2021)
    Параллелизм в алгоритмах — выявле́ние и рациональное его использование. Возможности компьютерного моделирования (https://habr.com/ru/post/688196/, 14.09.2022)
    Построение планов параллельного выполнения программ для процессоров со сверхдлинным машинным словом (проект) (https://habr.com/ru/articles/792744/, 10.02.2024)

  2. Весной 2009 г. сотрудник Баканов В.М. серьёзно заинтересовался пото́ковыми (DATA-FLOW) вычислительными системами (до этого интерес ре́ченного находился в области многопроцессорных систем класса BEOWULF, для чего были разработаны как приборная база, так и комплект учебно-методических материалов для кафедры ИТ-4 МГУПИ; сейчас МИРЭА). Причиной охлажде́ния интереса к HPC (Hight Perfomance Computing) - технологиям в реализации MPP-систем стало осмысле́ние необходимости изли́шне трудной и кропотливой работы по выявлению (скрытого) параллелизма и программированию его посре́дством известных технологий - напр., MPI (Message Passing Interface).

  3. К тому времени материалов по DATA-FLOW име́лось не столь много: несколько предельно упро́щенных статей из журнала "ЭЛЕКТРОНИКА: Наука, Технология, Бизнес" (напр., № 2 за 2002 годъ - здесь и здесь) и, конечно, WEB-сайт "команды Бурцева" (подозрительно, правда, что он не обновля́лся с 2006 г.). Ну и, конечно, вели́кое мно́жество самых разнокалиберных публикаций...
    Упрощенная структурная схема потокового вычислителя 
(журнал 'ЭЛЕКТРОНИКА: Наука, Технология, изнес', 2002, #2)

    Считается, что фундаментальные подходы управления процессом вычислений пото́ком данных (DATA-FLOW) в противове́с программному управлению (CONTROL-FLOW) предложил на рубеже 70-х г.г. Джек Деннис (Jack Dennis). Графическую модель пото́ковых (управляемых данными) вычислений обосновад в своей докторской диссертационной работе сотрудник Стэнфордского университета Дуайн Адамс (Duane Adams) в 1968 г.

    DATA-FLOW вычислительное устройство имеет кольцевую структуру; машинные инструкции и данные с признаками (то́кены) хранятся в единой сверхбыстродействующей ассоциативной памяти (АП), готовые к исполнению (ГКВ) по условию готовности их операндов инструкции с помощью входного коммутатора K1 выбираются из АП и передаются исполняющим устройствам (ИУ); результат выполнения оператора с помощью выходного коммутатора K2 записывается в АП и определяет готовность очередных операндов (а через них - и операторов). Т.о. рандеву́ команд и данных реализуется на исполняющих устройствах. ИУ могут быть арифметическими (АИУ) - выполняющими арифметические действия (кстати, поле АИУ не обязательно должно быть гомогенным - вычислительные возможности каждого могут различаться), служить для связи с внешними устройствами и др. Важно учесть, что режим выполнения параллельных частей программ в вычислителях DATA-FLOW является асинхронным (фактические каждое ИУ работает в своём временно́м режиме).
       В DATA-FLOW вычислителях реализованы правила обработки токенов, позволяющие реализовать многократное выполнение последовательности инструкций (т.е. организовывать циклы, переходы). Потоковые системы фактически реализуют принцип управления событиями на аппаратном уровне - каждый акт выполнения оператора на ИУ инициирует определе́ние нового списка ГКВ-инструкций, которые запускаются на исполнение на свободных ИУ.

  4. Совокупность идей и понятий (паради́гма) управля́емых да́нными (DATA-FLOW) вычислений (в противове́с управляемыми программой вычислениями - CONTROL-FLOW) отнюдь не сложна́. Преобразование (вычисление) r=a×b+a/c В качестве примера на рис. слева показаны различные методы вычисления величины r по трём заданным величинам a, b и c (т.е. преобразова́ние даных по правилу r←a×b+a/c).

       На фрагменте а) рисунка слева показано "облако операторов" (неструктурированный список операторов с указа́нием необходимых для выполнения каждого опера́ндов) согласно вышеприведённому преобразованию. В данном случае "облако" включает 3 оператора - a×b, a/c и a×b+a/c (последнее выражение здесь и далее означа́ет единственный оператор "сложе́ние"), причём порядок выполнения операторов не определён.
       На фрагменте б) приведён вариант последовательного выполнения операторов - сначала выполняются 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 раза.

  5. Основой распараллеливания на уровне операторов является представле́ние графа алгоритма (вычислительная модель "операторы ↔ операнды") в т.н. "я́русно-паралле́льной форме" (ЯПФ). Представление графа алгоритма в 
я́русно-параллельной форме Такой граф описывает информационные зависимости в алгоритме (вершины графа соответствуют отдельным операциям алгоритма, наличие дуги между вершинами i,j говорит о необходимости при выполнении операции j наличия аргументов (операндов), ра́нее выработанных операцией i; в случае независимости выполнения операций i и j дуга между вершинами отсутствует). Каждая вершина графа нагру́жена ме́рой - временем выполнения данной операции, а ребро - временем пересы́лки данных.
       С целью выявле́ния потенциала распараллеливания алгоритма его граф удобно предста́вить в ЯПФ; при этом из общего множества операторов выделяются группы (обычно представля́емые в виде я́русов), зави́симые (по операндам) только от результов выполнения операторов иного, предыдущего, яруса (на схеме слева отдельные я́русы расположены вертикально). Если число параллельно работающих исполнительных устройств ограничено, часть операторов может быть перенесено на более нижние ярусы; при этом время выполнения программы увеличится.

       Преобразование графа алгоритма к ЯПФ может быть вы́полнено вручную (при числе операторов порядка нескольких десятков), програ́ммным путем или с использованием вычислительных систем специальной архитектуры - пото́ковых (DATA-FLOW) вычислителей (уже на аппаратном уровне).

  6. Разработана компьютерная модель-симулятор пото́кового (DATA-FLOW) вычислителя статической архитектуры (новая версия "лето 2022" с возможностью моделирования стратегий управления интенсивностью вычислений, вы́дачей графика функции интенсивности вычислений, (встро́енным) препроцессором для обработки линейных псевдо-массивов и предикатным управлением выполнения операторов: инсталляционный файл INSTALL_DF.EXE (размер 2,7 Mбайт, Win'32, GUI; вариант гомогенного поля АИУ) + руководство Исследователя. Пользовательский интерфейс несложного
программного симулятора DATA-FLOW - вычислителя

    Свидетельство о регистрации программного продукта    Компьютерный симулятор позволяет выполнять счётные программы в стиле DATA-FLOW, обладает ра́звитой системой протоколирования работы, даёт возможность вести статистику работы отдельных элементов вычислителя (при учёте относительного времени выполнения отдельных инструкций), определять величину интенсивности вычислений - функцию числа параллельно выполняющихся операций по ходу решения задачи и др. (данные выводятся в файлы заданного формата с целью последующего импорта для анализа сторо́нними программами - например, построе́ния графики в MS Excel).
    На данное программное обеспечение получено (совместно с аспирантом Ханжиным Д.А.) СВИДЕТЕЛЬСТВО о государственной регистрации программ для ЭВМ № 2013614155 (Федеральная служба по интеллектуальной собственности Российской Федерации - Роспатент, заявка № 2013610527, дата поступления 24.I.2013 г., зарегистрировано в Реестре программ для ЭВМ 24.IV.2013 г.).

  7. Пример моделирования вычислений на DATA-FLOW машине - загру́женность отдельных исполнительных устройств (ИУ) при реше́нии СЛАУ 5-го порядка прямым методом Гаусса без выбора главного элемента (приведе́ние к верхней правой треугольной матрице и обратный ход). Интенсивность вычислений в функции времени 
выполнения программы (решение СЛАУ 5-го порядка 
прямым методом Гаусса)
       Бросается в глаза явно вы́раженная неравноме́рность (арбитра́ж "готовых к исполнению" операций не производился) функции интенсивности вычислений I(t); пунктиром показана некоторым о́бразом усреднённая зависимость I(t).
       Показанные на рис. справа неравномерности ("шква́лы" интенсивности вычислений) объясняются собственно принципами работы пото́кового вычислителя - сле́дствием выполнения на ИУ каждого оператора является устано́вка в состояние готовности множества входных операндов иных операторов, для которых результат выполнения данного является входным операндом.
       Подобная неравномерность не сули́т ничего хорошего - ведь её следствием является не менее вы́раженная неравномерная нагрузка на шины передачи данных (в первую очередь входного коммутатора, да и выходного тоже)... а это как раз самые слабые места пото́ковых вычислительных структур - именно тут и начинаются всяческие неприятные вещи - аппаратные го́нки и т.п. штуки... что делать - это один из (известных) недостатков SMP-подобной архитектуры!
       Классическим методом снижения нагрузки на шины данных SMP-вычислителя является принудительная (обычно небольшая сравнительно с характе́рным временем выполнения машинных инструкций) задержка в моментах начала передачи данных; при этом неизбежно возрастание общего времени выполнения программы (компенсируемое, впрочем, возможностью заде́йствования бо́льшего количества ИУ). При этом приобретает значение порядок за́пуска на исполнение команд, с помощью которого можно управлять интенсивностью вычислений.

  8. Графики интенсивности вычислений (сгла́женные кривые) при разреше́нии СЛАУ 2÷5-того порядка прямым методом Гаусса при неограниченном количестве ИУ (кривые 2÷5 соответственно) и решение СЛАУ 5-того порядка при их ограниченном числе (6 и 12 исполнительных устройствах для кривых 5/6 и 5/12 соответственно). Интенсивность вычислений в функции времени 
выполнения программы (2-5 - решение СЛАУ 2-5-го 
порядка соответственно, 5/6 и 5/12 - решение СЛАУ 
5-го порядка на 6 и 12 исполнительных устройствах)

    Видно, что характер функции I(t) неизменен для конкретного алгоритма, величина же э́кстремума интенсивности вычислений пропорциональна квадрату разме́рности данных.

       ...Интересно, почему так? Особенно если вспомнить, что функция вычислительной сложности алгоритма умножения матриц принадлежит классу O(N3) ...

    Что-то характер полученных кривых напоминает функцию вероятности распределения Пуассона с небольшим математическим ожиданием... Уж не является процесс вычислений (как минимум в данном случае) одним из вариантов процессов массового обслуживания?..

  9. На основе экспериментов предло́жено обладающее бо́льшей о́бщностью понятие динамической вычислительной сложности, учитывающее не только общее число операций, но и характер накопле́ния обработанной части их по ходу вычислений (нако́пленная кривая числа вычислений - фактически это интеграл от функции интенсивности вычислений I(t), вычисленный в преде́лах от начала процесса до текущего момента времени). Обобщённая функция динамической
вычислительной сложности Эта функция расширяет и уточняет привы́чную функцию скорости ро́ста числа вычислений от размеров обрабатываемых данных - та фактически учитывает только коне́чный результат выполне́ния алгоритма, но не уточняет, по какому закону растёт число вы́полненных операций по ходу вычислительного процесcа.

       Пример графика обобщённой функции динамической вычислительной сложности приведен на рис. справа, где число выполненных операций N показано в функции как размера обрабатываемых данных n, так и времени t процесса вычислений. На самом деле, конечно, параметры n и t не являются, строго говоря, ортогональными вследствие явно просле́живаемой зависимости t(n); однако правомо́чность рассмотре́ния и анализа зависимости N(n,t) заключается в я́вном указа́нии формы кумулятивной кривой вы́полненных операций.

       Т.о. сре́зы функции N(n,t) при t=const представляют собой классическую функцию вычсложности, сре́зы при n=const представляют собой нако́пленные (кумулятивные) функции числа вы́полненных операций (интеграл функции интенсивности вычислений).

  10. Очень бы хотелось иметь возможность хоть каким-то образом влиять на вид функции I(t) интенсивности вычислений... Например, в случае многозадачного режима интенсивность вычислений будет изменяться приблизительно так, как показано на схеме ниже. Интенсивность вычислений в случае
многозадачного режима

    Видно, что и в этом случае неравномерность функции интенсивности вычислений I(t) по времени остаётся значительной.

    Так что разработка методов её целенапра́вленного изменения остаётся заманчивым делом!

  11. А если воспользоваться тем, что каждый из операторов обладает разным влиянием на возможность выполнения иных операторов, зависящих от его (через свои собственные операнды, которые являются результатом выполнения данного)?

    Логично, например, ввести критерий "полезности" ("перcпективности") каждого оператора с точки зрения выполнения коне́чной цели - скоре́йшего завершения программы (напр., предположить, что "полезность" оператора зависит от количества иных операторов, которым данный обеспечивает готовность их входных операндов).

    При таком подходе в простейшем случае для оператора i его "перспективность" Pi определяется числом операторов j, выполнение ко́их зависит (по операндам) от исполнения данного, тогда Pi=j. Если учитывать вес каждого (из общего числа nj ; обычно nj=1÷2, но в общем случае может быть любым) входного операнда, получаем Pi=(1/nj) и т.д. Де́йственность каждого метода возможно проверить путём компьютерного моделирования процесса вычислений на DATA-FLOW машине.

    В новой версии симулятора DATA-FLOW вычислителя предусмотрена возможность моделирования различных стратегий управления интенсивностью вычислений. Влияние различных стратегий
управления интенсивностью вычислений

       Результаты компьютерного моделирования стратегий управления интенсивностью вычислений приведены на рисунке справа (на примере решения СЛАУ 5-го порядка). При единичном арифметическом исполняющем устройстве (АИУ) имеем чисто последовательный вычислитель, при числе АИУ более 24 (максимальное число ГКВ-операций для данного алгоритма) полностью реализуется потенциал распараллеливания (пятикратное ускорение вычислений).
       Обозначения на рисунке: 1 - равноприоритетное выполнение ГКВ-инструкций, 2 - режим интенсификации, 3 - депрессивный режим. Зависимости 2 и 3 соответственно иллюстрируют применению одной из стратегий управления ИВ c целью интенсификации процесса вычислений и его депрессии (по сравнению с равноприоритетной вы́боркой ГКВ-инструкций из буфера - линия 1).
       Режимы интенсификации и депрессии в процессе вычислений, естественно, могут целенаправленно перемежа́ться; при значительном количестве операций в алгоритме эффективность подобного управления возрастает.
       Итак, обоснована и доказана на уровне математического моделирования и компьютерной симуляции возможность целенаправленного управления интенсивностью вычислений в процессорах пото́ковой архитектуры, что даёт возможность, в частности, "разру́ливать" узкие места DATA-FLOW вычислителя (регулировать трафик внутрикристальных шин обмена данными, минимизируя последствия его "шква́листого" характера).

  12. В системе команд программного пакета SPF@home программа определения вещественных корней полного квадратного уравнения такова́ (символ ';' означает комментарий до конца строки):

    График интенсивности вычислений для алгоритма SQUA_EQU_2.SET ; Решение полного квадратного уравнения в вещественных числах 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)

    Свидетельство о регистрации программного продукта Летом 2022 г. (Крым, Щёлкино & Чокрак) создана версия (ver. 4.6) симулятора DATA-FLOW вычислителя с использованием предика́тов с целью управления последовательностью вычислений. Автор убеждён, что предика́тное выполнение операций - наилучшее решение для потоко́вого (DATA-FLOW) вычислителя, ибо идеально соответствует основной идеологе́ме указанной о́ного архитектуры - "правильным образом организованные ДАННЫЕ управляют ПОСЛЕДОВАТЕЛЬНОСТЬЮ ИХ ОБРАБОТКИ"; см. инсталляционный файл INSTALL_DF.EXE (размер 2,7 Mбайт, Win'32, GUI; вариант гомогенного поля АИУ) + руководство Исследователя.
       Формально введены́ бина́рные флаги, управляющие выполнением (или наоборот) каждой арифметико-логической операцией (аналогично архитектуры IA-64) и реализованы (двуме́стные) операции над предикатами (конъюнкция, дизъюнкция, импликация, эквивале́нция); более сложные операции над предикатами предполагается выполнять последовательно в идеологе́ме двуме́стного синтаксиса. Важным преимуществом предикатного подхода управления последовательностью выполнения операций является отсутствие инструкций безусловного и условного переходов в коде программы, что кардинально упрощает анализ и оптимизацию программ в форме информационного графа алгоритма.
       Благодаря добавления флага-предиката в виде последнего в списке параметров операции достигается полная совместимость с прежней системой команд - при отсутствии предиката он (по умолчанию) считается true.
       На данное программное обеспечение получено СВИДЕТЕЛЬСТВО о государственной регистрации программ для ЭВМ № 2018665726 (Федеральная служба по интеллектуальной собственности Российской Федерации - Роспатент, заявка № 2018662732, дата поступления 13.X.2018 г., зарегистрировано в Реестре программ для ЭВМ 10.XII.2018 г.).

       Формат команды с использованием предиката приведён ниже (квадратные скобки означают необязательность заключённого в них текста) :

    ADD Op1 [, Op2], Res [?|, Pred] [; комментарий до конца строки]

    где ADD – мнемоника команды (здесь - сложение), Оp1 и Оp2 – аргументы команды, Res – результат выполнения команды, Pred – необязательное имя предиката, символом-разделителем перед полем предиката могут служить ‘?’ или ‘,’, перед именем предиката допускается символ отрицания ‘!’.

       Нижеприведён пример использования этого подхода для нахожде́ния ВСЕХ (как вещественных, так и мнимых) корней полного квадратного уравнения (представлен текст соответствующей программы):

    График интенсивности вычислений для алгоритма SQUA_EQU_2.PRED.SET ; Нахожде́ние корней полного квадратного уравнения 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 ; Поиск максимума в массиве с использование предикатов
    ; используется алгоритм последовательного сравнения чисел в массиве
    ;
    ; файл 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

       Третий пример - поиск максимумума элементов массива чисел (длиной 8 элементов) методом сдва́ивания (аналогично проводится суммирование, умножение etc - ассоциативные операции):

    График интенсивности вычислений для алгоритма MAX-2_MASS-8.PRED.SET ; Поиск максимума в массиве с использование предикатов
    ; используется алгоритм сдва́ивания
    ;
    ; файл 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

    Тематические публикации по теме на HABR'е:

    Есть ли параллелизм в произвольном алгоритме и как его использовать лучшим образом (https://habr.com/ru/post/530078/, 26.11.2020)
    Такие важные короткоживущие данные (https://habr.com/ru/post/534722/, 24.12.2020)
    Это непростое условное выполнение (https://habr.com/ru/post/535926/, 03.01.2021)
    Динамика потокового вычислителя (https://habr.com/ru/post/540122/, 01.02.2021)
    Параллелизм и плотность кода (https://habr.com/ru/post/545498/, 05.03.2021)
    Сколько стоит расписание (https://habr.com/ru/post/551688/, 10.04.2021)
    Параллелизм в алгоритмах — выявле́ние и рациональное его использование. Возможности компьютерного моделирования (https://habr.com/ru/post/688196/, 14.09.2022)

  13. При возникнове́нии вопросов пиши́те разрабо́тчику на e881e@mail.ru Исходные коды программы на репозитарии GitHub

  14. Возврат к главной странице сайта Возврат к главной странице