Программирование для встроенных систем - статьи

       

Использование характерных особенностей ЦПОС


В этом разделе приведены преобразования, несложные для реализации, но представляющие интерес, поскольку опираются на внутренние особенности ЦПОС.

Раскладка локальных переменных по банкам памяти. В основе данного оптимизирующего преобразования лежит тот факт, что гарвардская архитектура предоставляет возможность параллельного доступа к двум ячейкам, при условии, что они находятся в различных памятях. Таким образом, появляется возможность ускорить доступ к данным при одновременном сокращении размера программного кода [11].

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

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

Частичное дублирование данных [11] оказывается полезным для оптимизации работы с участками кода подобными приведённому ниже:

for(n=1; n<r; n++) { R[n] +=signal[n] * signal[n+m]; }

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

Данный фрагмент можно существенно ускорить за счёт дублирования значений

signal[n] в двух банках памяти. Найти массивы-кандидаты на дублирование несложно – области жизни двух обращений к одному и тому же массиву должны пересекаться.

Дублирование данных не всегда приводит к повышению производительности. В частности, если в последствии не удастся запаковать оба обращения в одну инструкцию. В этом случае дублирование данных только ухудшает программу.

Кроме того, дублирование может усложнить работу с прерываниями.


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

Использование аппаратной поддержки циклов. В ЦПОС присутствует поддержка аппаратных циклов. Генерация кода для этого случая, в принципе, тривиальна: если имеется информация об исходном цикле, необходимо проверить что этот цикл удовлетворяет некоторым условиям:

  1. внутри цикла нет ветвлений и вызовов процедур
  2. границы цикла известны и фиксированы
  3. тело цикла не зависит напрямую от переменной индукции
  4. тело цикла не содержит запрещённых инструкций


В данном случае важно, что компилятор сохраняет информацию о циклах до довольно поздней стадии: стадии, когда уже сгенерирован код. Например, в SPAM это достигается за счёт того факта, что SUIF, используем в качестве front-end, позволяет «протаскивать» информацию об исходных циклах через весь слой машиннонезависимых оптимизаций и генерации кода.


Содержание раздела