Обновить 10. Реализация алгоритмов на основе анализа потока данных (черновик)

2024-01-13 12:16:19 +00:00
parent d71c29e947
commit 6c1f6012e7

@@ -29,7 +29,7 @@
Начинается всё с того, что каждой вершине приписывается два счётчика: `cnt_in = cnt_out = 0`. Данные блока `A` более свежие чем данные блока `B`, если `A->cnt_out > B->cnt_in`. `A->doStep()` перебирает все блоки `B` такие, что блок `B` имеет более свежие данные чем `A`, то есть `B->cnt_out > A->cnt_in`. Для каждого такого блока `B` он обновляет множество `A->IN` данными из `B->OUT` через `A->addIn(B->getOut())`. И для тех данных, которые действительно обновили `A->IN` он вызывает `A->forwardData()`. (На самом деле берётся не вся коллекция `B->getOut()` сразу целиком, а каждый её элемент сначала попадает в `addIn`, а затем, если `addIn` возвращает `true`, попадает в `forwardData`). При этом в `cnt_in` (`cnt_out`) попадает максимальное значение счётчика `cnt_out` среди блоков, которые добавили в множество `IN` (при помощи `addIn`) хоть один новый элемент (соответственно добавили в `OUT` при помощи `forwardData` хоть один новый элемент). Если данная вершина вызывает `doStep` впервые, то в конце [к `cnt_in` и `cnt_out` прибавляем по 1][**TODO: это не правильно, нужно потом исправить в коде и здесь**] чтобы обозначить, что в `OUT` этой вершины есть данные, которые появляются изначально при создании вершины и которые нужно распространить в остальные вершины. Начинается всё с того, что каждой вершине приписывается два счётчика: `cnt_in = cnt_out = 0`. Данные блока `A` более свежие чем данные блока `B`, если `A->cnt_out > B->cnt_in`. `A->doStep()` перебирает все блоки `B` такие, что блок `B` имеет более свежие данные чем `A`, то есть `B->cnt_out > A->cnt_in`. Для каждого такого блока `B` он обновляет множество `A->IN` данными из `B->OUT` через `A->addIn(B->getOut())`. И для тех данных, которые действительно обновили `A->IN` он вызывает `A->forwardData()`. (На самом деле берётся не вся коллекция `B->getOut()` сразу целиком, а каждый её элемент сначала попадает в `addIn`, а затем, если `addIn` возвращает `true`, попадает в `forwardData`). При этом в `cnt_in` (`cnt_out`) попадает максимальное значение счётчика `cnt_out` среди блоков, которые добавили в множество `IN` (при помощи `addIn`) хоть один новый элемент (соответственно добавили в `OUT` при помощи `forwardData` хоть один новый элемент). Если данная вершина вызывает `doStep` впервые, то в конце [к `cnt_in` и `cnt_out` прибавляем по 1][**TODO: это не правильно, нужно потом исправить в коде и здесь**] чтобы обозначить, что в `OUT` этой вершины есть данные, которые появляются изначально при создании вершины и которые нужно распространить в остальные вершины.
Теперь осталось только решить задачу с заполнением `nodes`. Эту задачу берёт на себя метод `fit()`. Реализация этого метода отличается в случаях, когда рассматривается задача прямого и обратного анализа потока данных. До этого повествование шло так, будто мы рассматриваем задачу прямого обхода. Поэтому в случае прямого обхода nodes заполняется естественно в топологическом порядке, то есть так, чтобы выполнялось соотношение, что для любых `i < j` дуги из `nodes[i]` в `nodes[j]` либо нет, либо это обратная дуга графа потока управления (см функцию `sortCfgNodes`). Для каждой созданной вершины `node` нужно заполнить Теперь осталось только решить задачу с заполнением `nodes`. Эту задачу берёт на себя метод `fit()`. Реализация этого метода отличается в случаях, когда рассматривается задача прямого и обратного анализа потока данных. До этого повествование шло так, будто мы рассматриваем задачу прямого обхода. Поэтому в случае прямого обхода nodes заполняется естественно в топологическом порядке, то есть так, чтобы выполнялось соотношение, что для любых `i < j` дуги из `nodes[i]` в `nodes[j]` либо нет, либо это обратная дуга графа потока управления (см функцию `sortCfgNodes`). Для каждой созданной вершины `node` нужно заполнить:
* `rollback` - множество `i` таких что есть обратная дуга `node -> nodes[i]` * `rollback` - множество `i` таких что есть обратная дуга `node -> nodes[i]`
* `prev_blocks` - множество всех вершин, из которых в node могут попасть данные (для задачи прямого обхода - это `nodes[i]` такие что есть дуга `nodes[i] -> nodes`; для задачи обратного прохода - это `nodes[i]`: есть дуга `node -> nodes[i]`). * `prev_blocks` - множество всех вершин, из которых в node могут попасть данные (для задачи прямого обхода - это `nodes[i]` такие что есть дуга `nodes[i] -> nodes`; для задачи обратного прохода - это `nodes[i]`: есть дуга `node -> nodes[i]`).