Функциональная декомпозиция

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

Предположим наша задача сводится к применению некоего функционального оператора к большому массиву данных: S[i]=F(a[i]). Предположим также, что выполнение функции F над одним элементом массива занимает достаточно большое время и нам хотелось бы это время сократить. В этом случае мы можем попытаться представить исходную функцию как композицию нескольких фунуций: S(a[i])=I(H(R(a[i]). Произведя декомпозицию мы получим систему последовательных задач:

x=r(a[i]);
y=h(x);
b[i]=i(y);

Каждая из этих задач может быть выполнена на отдельном узле кластера. Как можно заметить общее время обработки одного элемента массива a[i] в результате не изменяется, а скорее немного увеличивается за счет межпроцессорных пересылок. Однако общее время обработки всего массива заметно снижается за счет того, что в нашем примере одновременно идет обработка сразу трех элементов массива.

 

У данного метода декомпозиции есть пара особенностей, о которых надо помнить.

Первая особенность сосотоит в том, что выход кластера на максимальную эффективность происходит не сразу после запуска задачи, а постепенно, по мере того, как происходит частичная обработка первого элемента массива. Второй и третий процессоры в нашем примере, которые отвечают за выполнение функций g(x) и f(y), будут простаивать до тех пор, пока не закончится выполнение функции h(a[1]) на первом процессоре. Третий процессор будет простаивать до окончания выполнения функции g(a[1]). По аналогичному сценарию, только в зеркальном отображении, происходит окончание работы.

Вторая особенность заключается в выборе декомпозированных функций h,g,f. Для уменьшения времени простоя процессоров в ожидании следующей порции работы необходимо таким образом подбирать декомпозированные функции, чтобы время их работы было примерно одинаковым.

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