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

 
 
> [avr-gcc]Как побороть лишнюю оптимизацию?
UniBomb
сообщение Feb 4 2009, 13:38
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 148
Регистрация: 26-05-05
Пользователь №: 5 416



Добрый день. Столкнулся вот с какой незадачей - компиляция программы происходит так, что часть одной функции как бы выбрасывается из программы. Ошибок в функции нет, но что там говорить, вот эта функция:

(функция "как есть", в целях понимания ничего не убирал, надеюсь поймёте)

Код
void processing_data(void)
{
if(mdns.mdfl[U] <= mdns.mdfl[PGSU1])
  { mdns.mdfl[Conc] = mdns.mdfl[A1]*mdns.mdfl[U] + mdns.mdfl[B1]; }
else
  { mdns.mdfl[Conc] = mdns.mdfl[A2]*mdns.mdfl[U] + mdns.mdfl[B2]; }
  
char _s_disrec = 0;
if(mdns.mdfl[Conc] < 0) { mdns.mdfl[Conc] = 0; }
if(mdns.mdfl[Conc] >= mdns.mdfl[Pr])
  { pereg(); }
else if(mdns.mdfl[Conc] >= /*mdns.mdfl[P2]*/0.88)
  {
   _s_disrec = 1;
   if((flags&0x03 == 0) || (flags&0x03 == 1)) //если нет порогов или только первый
    {
     mdns.mdui[P1Count]++;
     mdns.mdui[P2Count]++;  
     WriteByteIntoExtEEPROM(0X3E, mdns.mdWorkSpace[0X46]);
     WriteByteIntoExtEEPROM(0X3F, mdns.mdWorkSpace[0X47]);
     WriteByteIntoExtEEPROM(0X40, mdns.mdWorkSpace[0X48]);
     WriteByteIntoExtEEPROM(0X41, mdns.mdWorkSpace[0X49]);    
     modbus_buf[9] = mdns.mdWorkSpace[0x48];//p2
     modbus_buf[8] = mdns.mdWorkSpace[0x49];//p2    
     modbus_buf[7] = mdns.mdWorkSpace[0x46];//p1
     modbus_buf[6] = mdns.mdWorkSpace[0x47];//p1    
    }
   flags |= (1 << 1);
   flags &= ~(1 << 0);
   modbus_buf[2] = flags;  
  }
else if(mdns.mdfl[Conc] >= mdns.mdfl[P1])
  {
   if(flags&0x03 == 0)         //если небыло до этого порога
    {
     mdns.mdui[P1Count]++;
     WriteByteIntoExtEEPROM(0X3E, mdns.mdWorkSpace[0X46]);
     WriteByteIntoExtEEPROM(0X3F, mdns.mdWorkSpace[0X47]);
     modbus_buf[9] = mdns.mdWorkSpace[0x48];//p2
     modbus_buf[8] = mdns.mdWorkSpace[0x49];//p2    
    }
   flags |= (1 << 0);      
   flags &= ~(1 << 1);
   modbus_buf[2] = flags;  
  }
else
  {
   flags &= ~(1 << 0);
   flags &= ~(1 << 1);
   modbus_buf[2] = flags;    
  }
  if(_s_disrec == 0)
   stop_disrec |= 0x0F;
}


если упрощённо, то функция делает следующее:

Код
void processing_data(void)
{
расчитываем некое значение mdns.mdfl[Conc]
  
if(проверяем - невышло ли значение сверх всяких норм)
  если да, то орём всем, чем можем и записываем сей факт в журнале

else if(проверяем - не слишком ли близко подошло значение к "сверх всяких норм")
  {
    верещим пищалкой, зажигаем два светодиода и делаем запись в журнале
  }

else if(проверяем - не превысило ли значение из ряда "нормальных значений")
  {
    верещим пищалкой, зажигаем один светодиод и делаем запись в журнале
  }

else
  {
   всё хорошо, продолжаем как ни в чём небыло
  }

}


Так вот - вне зависимости от значения во второй и тетий if программа незаходит. Т.е. зачение расчитывается, я его спрашиваю по модбасу, оно соответсвует действительности, но ни один светодиод не загорается и звуковой извещатель всё время молчит. Поэтому я даже не знаю - толи эти if'ы не вошли в готовую программу, либо всё время заходит в последний иф. В живую получить значения выше mdns.mdfl[Pr] у меня нет возможности, поэтому этот if мне не проверить.

В процессе отладки я закомментировал расчёты mdns.mdfl[Conc] просто присваивал этой переменной различные значения. Результат тотже (это в принципе неудивительно, тут ещё можно поверить оптимизатору), но если я этой переменной присваивал значение выше чем mdns.mdfl[Pr], то в первый if программа заходит. Из этого я могу сделать вывод, что оптимизации поддались все остальные if'ы. Можно ли это как-нибудь побороть?


прочие исходные данные : avr-gcc (WinAVR 20080512) 4.3.0; уровень оптимизации "s" (меньше ставить нельзя, больше смысла нет).
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
UniBomb
сообщение Feb 5 2009, 06:26
Сообщение #2


Частый гость
**

Группа: Свой
Сообщений: 148
Регистрация: 26-05-05
Пользователь №: 5 416



а без оптимизации размер программ превышает размер памяти мк smile.gif Самый низкий уровень оптимизации, на выходе которой рзмер программы позволяет прошиться в мк - 2. Но при этом всё остаёться без изменений...
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Feb 5 2009, 06:37
Сообщение #3


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(UniBomb @ Feb 5 2009, 09:26) *
а без оптимизации размер программ превышает размер памяти мк smile.gif

Значит, надо взять пожирнее. Делать что-то без запаса - неразумно. Я за год одну прошивку последовательно пропатчил с 15 до 22 кБ.
А вы что будете делать потом, ели вдруг (да наверняка) ещё что-нибудь добавится?

PS: буферы свои объявите volatile, наверняка в прерывании их меняете


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
UniBomb
сообщение Feb 5 2009, 06:57
Сообщение #4


Частый гость
**

Группа: Свой
Сообщений: 148
Регистрация: 26-05-05
Пользователь №: 5 416



Цитата(MrYuran @ Feb 5 2009, 09:37) *
Значит, надо взять пожирнее. Делать что-то без запаса - неразумно. Я за год одну прошивку последовательно пропатчил с 15 до 22 кБ.
А вы что будете делать потом, ели вдруг (да наверняка) ещё что-нибудь добавится?

PS: буферы свои объявите volatile, наверняка в прерывании их меняете


Насчёт запаса - просто есть уже готовое устройство, которое прошло все стадии разработок и меняться уже не будет. Более того - программа по всё это дело тоже уже готовая и запас свободного места составляет 25%. Эта ерунда проявилась после последней правки программы (до этого всё было нормально) и принципиально нового в принципе уже ничего не добавиться. Также следуя правилу о преждевременной оптимизации кода я этой оптимизацией и не занимался (я имею в виду С-шный код, который я пишу, а не компилятор). Думаю после этого свободного места будет процентов 40. Сейчас размер прошивки ~6,3 кб, использую восьмую атмегу с 8кб памяти.


насчёт постскриптума - а разве volatile влияет на то, что эти переменные как то изменяются в прерывании? Объясните этот момент поподробней пожалуйста (я правда это не знаю biggrin.gif )
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Feb 5 2009, 07:38
Сообщение #5


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(UniBomb @ Feb 5 2009, 09:57) *
принципиально нового в принципе уже ничего не добавиться

к.г. правка программы заканчивается со смертью программиста biggrin.gif (и то не всегда)
Цитата
насчёт постскриптума - а разве volatile влияет на то, что эти переменные как то изменяются в прерывании?

volatile объясняет компилятору, что не нужно слишком умничать и оптимизировать данную переменную.
Он же не знает, что она может измениться где-то в другом потоке, и может решить, что раз переменная явно нигде не меняется, то и результат сравнения будет "как в прошлый раз".
Я утрирую конечно, но просто все переменные, которые используются одновременно в прерываниях и где-то ещё, всегда объявляют как volatile.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
UniBomb
сообщение Feb 5 2009, 08:03
Сообщение #6


Частый гость
**

Группа: Свой
Сообщений: 148
Регистрация: 26-05-05
Пользователь №: 5 416



Цитата(MrYuran @ Feb 5 2009, 10:38) *
к.г. правка программы заканчивается со смертью программиста biggrin.gif (и то не всегда)

biggrin.gif


Цитата(MrYuran @ Feb 5 2009, 10:38) *
volatile объясняет компилятору, что не нужно слишком умничать и оптимизировать данную переменную.
Он же не знает, что она может измениться где-то в другом потоке, и может решить, что раз переменная явно нигде не меняется, то и результат сравнения будет "как в прошлый раз".
Я утрирую конечно, но просто все переменные, которые используются одновременно в прерываниях и где-то ещё, всегда объявляют как volatile.

Объявил с volatile. Ничего не изменилоь... И кстате свои буферы я изменяю в каждой второй функции. Я не зря объявил msdn как union - этот буфер я передаю по модбасу, по своему "техническому" протоколу как по частям, так и всем буфером сразу, в процессе работы отдельные части изменяються постояно.
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 24th July 2025 - 10:53
Рейтинг@Mail.ru


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