реклама на сайте
подробности

 
 
> Оптимизация прерываний, Прошу совета
Dmitro25
сообщение Mar 31 2010, 05:47
Сообщение #1


Участник
*

Группа: Свой
Сообщений: 60
Регистрация: 4-04-07
Пользователь №: 26 770



Здравствуйте.
Пишу проект на IAR for AVR.
Возникло желание посмотреть, какой код формирует компилятор для прерываний. Оказалось, что в начале процедуры прерывания сохраняется в data-stack, а конце - восстанавливается 15 регистров общего назначения, хотя вызываемые из прерывания функции не требуют такого количества регистров. Я сначала подумал, что всё дело в том, что вызываемая из прерывания функция находится в другом модуле проекта, перенёс её в тот же модуль, где находится процедура прерывания, но отличий не увидел. Такое же ненужное сохранение множества регистров.
Разумное сохранение регистров я увидел только тогда, когда компилятор включил текст вызываемой функции в процедуру прерывания (inline). Если по какой-то причине inline функции не получается, снова бессмысленное сохранение регистров.
Чтобы не быть голословным, привожу код:
Код
#include <ioavr.h>

#pragma optimize=no_inline
void DoNothing()
{
}

#pragma vector = TIMER1_COMPA_vect
__interrupt void ext_int0_isr_routine(void)
{
  DoNothing();
}

int main( void )
{
  return 0;
}

Оптимизация стоит максимальная по скорости.
Подскажите, как этого можно избежать? Очень хотелось бы из прерывания вызывать функции, в т.ч. из других модулей, и иметь при этом оптимальный код.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Dmitro25
сообщение Mar 31 2010, 10:31
Сообщение #2


Участник
*

Группа: Свой
Сообщений: 60
Регистрация: 4-04-07
Пользователь №: 26 770



2dxp:
Спасибо за советы.
Всё-таки не удержусь от такого комментария:
Цитата
Это откуда ему "ТОЧНО известно" это? Вот представьте, что вы компилятор, вам дали обработчик прерывания, в нем есть вызов функции, но кроме вызова ничего нет - самой функции вы не видите, ее исходного кода у вас нет, есть только прототип, чтобы вы могли ее правильно вызвать. Все.

В приведённом мною выше примере вызываемая функция расположена прямо в том же модуле, что и процедура прерывания, а результат тот же. Одно дело, если компилятору в качестве одного из модулей проекта предоставляется уже скомпилированный объектный файл и заголовочный - в этом случае трудно делать какие-то предположения об используемых в каждой функции регистрах. Во многих случаях компилятору известен исходный код подключаемых модулей проекта. Почему бы не сделать дополнительную оптимизацию, тем более, что для прерываний это весьма актуально?
Мне кажется, это происходит из-за того, что компилятор и линкер - это две разные программы. Если бы был некий компилятор+линкер, оптимизировать было бы легче. Хотя для исключения сохранения лишних регистров в прерывании достаточно было бы передать из компилятора в линкер список используемых в функции регистров, а также список подфункций, вызываемых из функции.
А насчёт замечания про "call": мне кажется, что задача превращения части инструкций "call" в "rcall" для коротких переходов вполне решаемая для компилятора. Это позволило бы немного сократить код и увеличить скорость. И, кстати, проверил, в CodeVisionAVR в данном случае функция из прерывания вызывается по команде "rcall".

2Сергей Борщ:
Цитата
Объявляйте их static (static inline, если компилятор позволяет) и выносите в заголовочный файл соответствующего модуля.

Если я правильно понял, Вы предлагаете в заголовочный файл вынести реализацию функции?
Я уже так и сделал, например, с функцией spi(). Однако, если данная функция должна иметь доступ к внутренним переменным модуля, возникают проблемы.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 31 2010, 10:51
Сообщение #3


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Dmitro25 @ Mar 31 2010, 12:31) *
Если я правильно понял, Вы предлагаете в заголовочный файл вынести реализацию функции?
Я уже так и сделал, например, с функцией spi(). Однако, если данная функция должна иметь доступ к внутренним переменным модуля, возникают проблемы.
Тогда внесите обработчик в сишный файл этого модуля.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Dmitro25   Оптимизация прерываний   Mar 31 2010, 05:47
- - mempfis_   КодВозникло желание посмотреть, какой код формируе...   Mar 31 2010, 06:34
- - Dmitro25   2mempfis: ЦитатаПопробуйте вместо вызова функции в...   Mar 31 2010, 06:47
|- - MrYuran   Цитата(Dmitro25 @ Mar 31 2010, 09:47) Под...   Mar 31 2010, 07:24
|- - dxp   Цитата(Dmitro25 @ Mar 31 2010, 13:47) Вот...   Mar 31 2010, 08:06
- - Dmitro25   2dxp: ЦитатаКак раз понятное и объяснимое поведени...   Mar 31 2010, 08:28
|- - dxp   Цитата(Dmitro25 @ Mar 31 2010, 15:28) 2dx...   Mar 31 2010, 09:26
|- - Сергей Борщ   Цитата(Dmitro25 @ Mar 31 2010, 10:28) пер...   Mar 31 2010, 09:33
|- - defunct   Цитата(Dmitro25 @ Mar 31 2010, 11:28) Зад...   Apr 4 2010, 23:06
|- - dxp   Цитата(Dmitro25 @ Mar 31 2010, 17:31) В п...   Mar 31 2010, 11:28
- - Dmitro25   2Сергей Борщ: ЦитатаТогда внесите обработчик в сиш...   Mar 31 2010, 11:48
|- - MrYuran   Цитата(Dmitro25 @ Mar 31 2010, 14:48) При...   Mar 31 2010, 12:59
- - MALLOY2   Вам же говорили глобальный флаг, а в основном цикл...   Mar 31 2010, 12:44
- - Dmitro25   2:MALLOY2 Глобальный флаг у меня в другом месте в ...   Mar 31 2010, 13:17
- - XVR   Что бы компилятор понял в процедуре прерывания, чт...   Apr 1 2010, 10:44


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 15:41
Рейтинг@Mail.ru


Страница сгенерированна за 0.01385 секунд с 7
ELECTRONIX ©2004-2016