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

 
 
> "Оптимизация" в WinAVR и как с этим бороться
MaxiMuz
сообщение Nov 16 2011, 18:07
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 253
Регистрация: 15-04-10
Из: Волгоград
Пользователь №: 56 658



Перейдя с ассемблера на WinAVR, невольно стал обращать на размер кода. Когда стал разбираться в конкретике генерируемого кода , хваленный на многих сайтах WinAVR обнажил свое несовершенство.
Короче, программка :
Код
#include <avr/io.h>
#include <inttypes.h>

#define Btn1 PB2
#define Btn2 PB3

#define  KeyMask (1<<Btn1)|(1<<Btn2)
#define sbi(p,b) (p |= (1<<b)) //Установить бит

volatile register int8_t Cnt asm("r19");    // фоновый счетчик
volatile register int8_t a asm ("r16");

int main (void)
{
asm("nop");
a = 1;

while(1)
{
if (~(PINB)&(KeyMask))
    {
    a |= 0x01;
    }
if ((--Cnt)==0)
    {
    if (a==1 )
        {
        a=0;
        sbi (PINB,PB2);
        }
    }
}
}

Соответственно , полученный код:
Код
a = 1;
     ldi    r16, 0x01

while(1)
{
[color="#FF00FF"]if (~(PINB)&(KeyMask))
     in     r24, 0x16
     ldi    r25, 0x00
     com    r24
     com    r25
     andi    r24, 0x0C
     andi    r25, 0x00
     or     r24, r25
     breq    .+2[/color]
{
a |= 0x01;
}
     ori    r16, 0x01

[color="#FF0000"]if ((--Cnt)==0)
     mov    r24, r19
     subi    r24, 0x01
     mov    r19, r24[/color]
     brne    .-26    
{
    if (a==1 )
     cpi    r16, 0x01
     brne    .-30
{
        a=0;
     ldi    r16, 0x00

sbi (PINB,PB2);
     sbi    0x16, 2
     rjmp    .-36

Конструкцию if ((--Cnt)==0) выделенную крас.цветом может заменить всего одна машинная команда: dec r19!
Вопрос: как заставить компилятор это делать ?

Во втором случае: if (~(PINB)&(KeyMask)) , невижу смысла во втором парном регистре r25. Можно использовать "tst r24". Можно как нибудь с этим бороться ?!
Не хочеться чтобы потом код получался неоправданно раздутым!
Может быть стоит подождать другую версию компилятора (пользуюсь WinAVR-20100110) или уже пререходить на совсем другой ?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
MaxiMuz
сообщение Nov 25 2011, 08:40
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 253
Регистрация: 15-04-10
Из: Волгоград
Пользователь №: 56 658



Спасибо за ответы !

Опять я возвращаюсь к своим любимым регистровым глобальным переменным.
Вначале программы обычно происходит инициализация переменных. В моей программе три регистровых глобальных переменных. Одна из них обьявленна как битовая область, и с ней проблем нет. Две других как беззнаковый байт (см. программу). В месте задания им начальных значений, компилятор игнорировал эти операции, чтобы я не делал. Все уровни оптимизации , кроме -O0 исключали эти команды. Но, после перемещения блока инициализации в отдельную подпрограмму , компилятор всеже их заметил, и правильно откомпилировал! У меня возникла мысль, что какието ключи не позволяют оптимизатору игнорировать команды в подпрограммах.
Хотел бы услышать ваши предположения.

Код
#include <avr/io.h>
#include <avr/interrupt.h>  // задает макросы sei() , cli()
#include <inttypes.h>

//=====================================================================
// определение регистров:
volatile register uint8_t FLCnt asm("r16"); //фоновый счетчик длительности переключения свдиода
volatile register uint8_t DBKCnt asm("r18"); //фоновый счетчик для отсчета периода блокировки опроса кнопок
volatile register struct
{
  uint8_t bDbRKey : 1;
  uint8_t bFLed : 1;
} RFGP asm ("r17");

//;----------------------------------------------------------------------------------------------------------------------------------------
//=== Определение макросов
#define sbi(p,b) (p |= (1<<b)) //Установить бит
//;----------------------------------------------------------------------------------------------------------------------------------------
//Определение портов:
/* направление для порта В*/
#define DIRB 0b00010001
/* Pull-ups для порта В*/
#define PUPB 0b00000101

//;----------------------------------------------------------------------------------------------------------------------------------------
//Определение контактов
#define Control1 PB4 /* линия управления VT (1 - откр; 0 - закр ) */
#define Btn1 PB2 /* линия кнопки (на общ.пров) */
#define Led PB0 /* линия светодиода ("1" - вкл. ч/з резистор на общ.) */

//;----------------------------------------------------------------------------------------------------------------------------------------
/* длительность запрета на опрос клавиш t=(101-1)*0,1=10 sec */
#define Vl_DBKCnt 101

/* t=5*0,1=0,5 sec */
#define Vl_FLCnt 5

// Маска кнопок:"Btn"
#define  KeyMask (1<<Btn1)|(1<<1)


//=====================================================================
//=====================================================================
SIGNAL ( SIG_OUTPUT_COMPARE0A)
{//______ Моргание светодиода t=5*0,1=0,5 sec
if (!(--FLCnt))
{//__ Переключение свдиода
  FLCnt=Vl_FLCnt;// перезагрузка ф.счетчика              !!!!
  ~(RFGP.bFLed);
  sbi (PINB,Led);// ________ Переключение свдиода !
}

//______ Формирование запрета на опрос клавиш t=(101-1)*0,1=10 sec
if (RFGP.bDbRKey==1)
{ //__ проверка на первый запуск
   if (DBKCnt == 0 )
    DBKCnt=Vl_DBKCnt;
   --DBKCnt;//__ продолжение счета
   if (DBKCnt==0) // checking of =0
   { //__ сброс флага
     RFGP.bDbRKey=0;
     DBKCnt=Vl_DBKCnt;
   }
}
}

//=============================================================================
//=============================================================================
int main (void)
{
//_________________________ ИНИЦИАЛИЗАЦИЯ _____________________________
uint8_t temp;

PORTB=PUPB; //иницализация порта B
DDRB=DIRB; // задание направления для порта B
TIMSK0=(1<<OCIE0A); /* установка разр. прер-ия по совпадению т/сч.0 с регистром OCR0A */
OCR0A=234; //загрузка регистра совпадения OCR0A коэф. деления
TCCR0A= (1<<WGM01); //установка режима СТС - обнуление Т/С0 при совпадении с регистром OCR0A
TCCR0B=(1<<CS02)|(1<<CS00); // <---- конфигурация и запуск сч-ка в реж. СТС с предделителем ckl/1024
RFGP.bDbRKey=0;
RFGP.bFLed=0;
[color="#ff0000"]DBKCnt=Vl_DBKCnt; //задание начальных значений для счетчиков
FLCnt=(uint8_t)Vl_FLCnt;[/color]

sei (); // Разрешение общего прерывания
//____________________ ЦИКЛ РАБОЧЕЙ ПРОГРАММЫ ______________________
while (1)
{ //____ Считывание кнопки
  temp=~(PINB);
  temp &= KeyMask;
  if (temp)
  {  //______ Обработка нажатия кн."Btn"
   if ( RFGP.bDbRKey==0)//____ проверка на запрет считывания кнопок
   { RFGP.bDbRKey=1; // sbr RFGP,(1<<bDbRKey)
     sbi (PINB,Control1); // ________ Переключение линии Control1 _______________!!!!!
   }
  }
}
}


Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Nov 25 2011, 09:27
Сообщение #3


Гуру
******

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



QUOTE (MaxiMuz @ Nov 25 2011, 11:40) *
Хотел бы услышать ваши предположения.
Прочитайте еще раз про яйцо и микроволновку. Мне лень считать, сколько раз вам писали, что регистровую переменную нельзя делать volatile, о чем прямым текстом пишут создатели компилятора. Вы же с упорством пьяного продолжаете писать register volatile и пенять на компилятор.


--------------------
На любой вопрос даю любой ответ
"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
MaxiMuz
сообщение Nov 25 2011, 12:07
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 253
Регистрация: 15-04-10
Из: Волгоград
Пользователь №: 56 658



Цитата(Сергей Борщ @ Nov 25 2011, 12:27) *
Прочитайте еще раз про яйцо и микроволновку. Мне лень считать, сколько раз вам писали, что регистровую переменную нельзя делать volatile, о чем прямым текстом пишут создатели компилятора. Вы же с упорством пьяного продолжаете писать register volatile и пенять на компилятор.

Извиняюсь что возмутил вас употребением и применением volatile !
Кстати сказать, из ответ на вопрос о использовании Volatile к регистровым глобальным переменным я со своим плохим знанием английского понял что компилятор уже считает регистровые переменные как volatile. Другими словами использование квалификатора бессмысленно.
Я убрал в обьявлении переменных FLCnt, DBKCnt volatile, результат тотже !
Вопрос остается открытым
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Nov 25 2011, 14:16
Сообщение #5


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(MaxiMuz @ Nov 25 2011, 18:07) *
Вопрос остается открытым

Какой?


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
ReAl
сообщение Nov 25 2011, 14:35
Сообщение #6


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(AHTOXA @ Nov 25 2011, 16:16) *
Какой?

Почему регистровые переменную, вне зависимости от наличя слова volatile, компилятор, предупредивший о своём отношении к таким объявлениям, не рассматривает как volatile и выкидывает из main() их инициализацию, так как в этой же main() к переменным больше обращений нет, а про обращение к ним из прерываний компилятор «не знает».


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Nov 25 2011, 19:17
Сообщение #7


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



По-моему, на этот вопрос тоже уже ответили, и не раз sm.gif
Я на всякий случай ещё раз повторю ответ: да, в этом моменте компилятор работает криво.
Варианты решения проблемы тоже вроде все предложены:
  1. Не использовать регистровые переменные.
  2. Использовать, но не в качестве volatile-переменных.
  3. Использовать, но для обращения к этим переменным применять подпрограммы на (инлайн-)ассемблере.



--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- MaxiMuz   "Оптимизация" в WinAVR и как с этим бороться   Nov 16 2011, 18:07
- - Палыч   Цитата(MaxiMuz @ Nov 16 2011, 22:07) хвал...   Nov 16 2011, 18:45
|- - MaxiMuz   Цитата(Палыч @ Nov 16 2011, 21:45) А, вот...   Nov 16 2011, 19:19
|- - Палыч   Цитата(MaxiMuz @ Nov 16 2011, 23:19) KeyM...   Nov 16 2011, 20:10
|- - MaxiMuz   Цитата(Палыч @ Nov 16 2011, 23:10) Почему...   Nov 16 2011, 21:06
|- - aaarrr   Цитата(MaxiMuz @ Nov 17 2011, 01:06) or ...   Nov 16 2011, 21:19
|- - MaxiMuz   Цитата(aaarrr @ Nov 17 2011, 00:19) Это о...   Nov 17 2011, 15:19
|- - Палыч   Цитата(MaxiMuz @ Nov 17 2011, 19:19) ... ...   Nov 17 2011, 17:42
|- - AHTOXA   Цитата(MaxiMuz @ Nov 17 2011, 21:19) А ес...   Nov 17 2011, 17:47
|- - _Pasha   Цитата(MaxiMuz @ Nov 17 2011, 19:19) Код ...   Nov 18 2011, 06:25
- - AHTOXA   Цитата(MaxiMuz @ Nov 17 2011, 00:07) Пере...   Nov 16 2011, 19:58
|- - MaxiMuz   Цитата(AHTOXA @ Nov 16 2011, 22:58) Вам ж...   Nov 18 2011, 09:00
|- - Палыч   Цитата(MaxiMuz @ Nov 18 2011, 13:00) На О...   Nov 18 2011, 10:59
||- - _Pasha   Цитата(Палыч @ Nov 18 2011, 13:59) Имхо, ...   Nov 18 2011, 14:36
|||- - neiver   Цитата(_Pasha @ Nov 18 2011, 18:36) и не ...   Nov 18 2011, 14:45
|||- - ReAl   Цитата(_Pasha @ Nov 18 2011, 16:36) ГЦЦ н...   Nov 18 2011, 16:17
|||- - demiurg_spb   Паша верно перечислил основные недочёты avr-gcc, с...   Nov 18 2011, 17:13
|||- - neiver   Цитата(ReAl @ Nov 18 2011, 20:17) Вот еще...   Nov 18 2011, 17:23
|||- - MaxiMuz   Цитата(neiver @ Nov 18 2011, 20:23) К сож...   Nov 20 2011, 11:58
|||- - ReAl   Цитата(MaxiMuz @ Nov 20 2011, 12:55) Хоте...   Nov 20 2011, 12:23
|||- - MaxiMuz   Цитата(ReAl @ Nov 20 2011, 15:23) ..........   Nov 23 2011, 11:30
|||- - demiurg_spb   Цитата(MaxiMuz @ Nov 23 2011, 15:30) где ...   Nov 23 2011, 13:39
||||- - ReAl   Тьху, ну конечно, -ffixed-reg Что-то меня на = пот...   Nov 23 2011, 21:19
|||- - AHTOXA   КодCFLAGS += -ffixed-r16 CFLAGS += -ffixed-r18   Nov 23 2011, 14:40
||- - MaxiMuz   Цитата(Палыч @ Nov 18 2011, 13:59) Если В...   Nov 18 2011, 16:06
||- - ReAl   Цитата(MaxiMuz @ Nov 18 2011, 18:06) боль...   Nov 18 2011, 22:38
|- - Сергей Борщ   QUOTE (MaxiMuz @ Nov 18 2011, 12:00) Это ...   Nov 18 2011, 11:54
- - ReAl   Цитата(MaxiMuz @ Nov 16 2011, 20:07) Код#...   Nov 16 2011, 21:53
- - Genadi Zawidowski   Код#define KeyMask (1<<Btn1)|...   Nov 17 2011, 01:30
- - neiver   Мда, можно вытащить ассемблерщика из ассемблера, н...   Nov 17 2011, 08:19
|- - Палыч   Цитата(neiver @ Nov 17 2011, 12:19) integ...   Nov 17 2011, 09:27
- - neiver   Я к чему, тут про целочисленное расширение намекаю...   Nov 18 2011, 05:25
- - MaxiMuz   neiver , _Pasha да действительно, можно и так напи...   Nov 18 2011, 08:38
|- - neiver   Цитата(MaxiMuz @ Nov 18 2011, 12:38) neiv...   Nov 18 2011, 08:44
- - neiver   GCC прекрасно может сгенерировать одну команду sbi...   Nov 18 2011, 11:07
|- - Палыч   Цитата(neiver @ Nov 18 2011, 15:07) GCC п...   Nov 18 2011, 11:17
- - ReAl   Жаль.   Nov 18 2011, 19:58
- - ReAl   Провёл маленький эксперимент. Убрал все эти regist...   Nov 25 2011, 20:32
- - MaxiMuz   AHTOXA с вами не поспоришь ReAl По сути , кусок...   Nov 28 2011, 10:59
|- - ReAl   Цитата(MaxiMuz @ Nov 28 2011, 12:59) подо...   Nov 28 2011, 14:16
- - sigmaN   перед main воткните __attribute__ ((noreturn)); h...   Nov 28 2011, 19:40
|- - MaxiMuz   Цитата(sigmaN @ Nov 28 2011, 22:40) перед...   Jan 23 2012, 09:15
- - ReAl   Для этого в AVR-GCC уже давно есть OS_main и OS_ta...   Nov 28 2011, 20:17
- - sigmaN   ну или так, да. а ещё я из исходников библиотеки ...   Nov 28 2011, 22:10
|- - ILYAUL   Цитата(sigmaN @ Nov 29 2011, 02:10) ну ил...   Nov 29 2011, 04:15
|- - ARV   Цитата(ILYAUL @ Nov 29 2011, 08:15) ИМХО ...   Jan 23 2012, 09:53
- - MaxiMuz   При использовании int OS_main (void) компилятор вы...   Jan 23 2012, 14:50
- - sigmaN   warning это не error и по идее не должен приводить...   Jan 24 2012, 02:07
|- - MaxiMuz   Цитата(sigmaN @ Jan 24 2012, 05:07) warni...   Feb 2 2012, 11:49
- - _Pasha   Таварисч не панимаит. Кодint main(void) __...   Feb 2 2012, 12:16
|- - MaxiMuz   Цитата(_Pasha @ Feb 2 2012, 15:16) Тавари...   Feb 3 2012, 10:42
|- - Сергей Борщ   QUOTE (MaxiMuz @ Feb 3 2012, 12:42) Да...   Feb 3 2012, 11:08
- - MaxiMuz   Доброго времяни суток! Не стал создавать отдел...   Oct 16 2012, 18:35
|- - Палыч   Цитата(MaxiMuz @ Oct 16 2012, 22:35) здес...   Oct 17 2012, 06:15
|- - MaxiMuz   Цитата(Палыч @ Oct 17 2012, 09:15) Это - ...   Oct 17 2012, 12:11
|- - Сергей Борщ   В этом стандарте операция "&" выполн...   Oct 17 2012, 12:59
|- - Палыч   Цитата(MaxiMuz @ Oct 17 2012, 16:11) стан...   Oct 17 2012, 13:04
- - Genadi Zawidowski   Используйте компилятор поновее (avr-gcc 4.7.2, avr...   Oct 16 2012, 19:26


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

 


RSS Текстовая версия Сейчас: 26th June 2025 - 08:45
Рейтинг@Mail.ru


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