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

 
 
 
Reply to this topicStart new topic
> Как бы оптимальней закодировать алгоритм, IAR AVR 6.1
_Артём_
сообщение Feb 1 2012, 01:02
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Здраствуйте.
Посоветуйте как оптимальней (по скорости исполнения) реализовать алгоритм для xmega256A3:
Обрабатываются 8 каналов ацп A и 8 каналов ацп B.
Каждый канал ацп суммируется 16 раз в прерывании таймера, кроме того каналы ацп а могут использоваться как логические входы (пороги задаются), и также перепады могут фиксироваться (инкремент счётчика). В каждом прерывании считываются и запускается 4 преобразования ацп а и 4 ацп Б.
CODE
#ifndef adc_h__
#define adc_h__

#include "avr_compiler.h"
#include "adc_driver.h"



#include "adc_driver.h"

struct TADC_AChannel {// данные канала на АЦП А
unsigned char Cnt;// счётчик передов
unsigned char CntUp;// считать фронт
unsigned char CntDown;// считать срез
unsigned char State;// состояние входа
unsigned char NextMux;// значение MUX
unsigned short LvlH, LvlL;// уровни 1 и 0
unsigned short Sum;// накопленная сумма
void Init(
unsigned short level_h, // уровень 1
unsigned short level_l, // уровень 0
unsigned char cnt_mode, // счёт. импульсов/ аналоговый вход
unsigned char state // начальное логическое состояние
) {
Cnt=0;
LvlH=level_h;
LvlL=level_l;
CntUp = (cnt_mode&1) ? (1) : (0);
CntDown = (cnt_mode&2) ? (1) : (0);
State=state;
}
void Exec(unsigned short new_value) {
if (Cnt) {
// режим счёта импульсов
if (State) {
if (new_value<LvlL) {
State=0;
if (CntDown)
Cnt++;
}
}
else {
if (new_value>LvlH) {
State=1;
if (CntUp)
Cnt++;
}
}
}
Sum+=new_value;
}
};

struct TADC_BChannel {// данные канала на АЦП А
unsigned short Sum;// накопление суммы
unsigned char NextMux;
void Exec(unsigned short new_value) {
Sum+=new_value;
}
};



class TAdc {
unsigned char ADCAMode;
volatile unsigned char ActiveArray;
volatile unsigned char SumReady;
struct TADC_AChannel AdcA[2][8];
struct TADC_BChannel AdcB[2][8];

volatile unsigned char ADCReady;
unsigned char CycleCnt;


public:
void StartNextConvervion()
{
TADC_AChannel *adc_ptr;

// определение текущего блока памяти для записи
unsigned char active_block = (ActiveArray) ? (1) : (0);
adc_ptr= (active_block) ? (&AdcA[1][0]) : (&AdcA[0][0]);

if (CycleCnt&1)
adc_ptr+=4; // чтение каналов 4-7
unsigned short adc_result;

// виртуальный канал 0 АЦП А
adc_result=ADCA.CH0.RES;
adc_ptr->Exec(adc_result);
ADCA.CH0.MUXCTRL=adc_ptr->NextMux;
adc_ptr++;

// виртуальный канал 1 АЦП А
adc_result=ADCA.CH1.RES;
adc_ptr->Exec(adc_result);
ADCA.CH1.MUXCTRL=adc_ptr->NextMux;
adc_ptr++;

// виртуальный канал 2 АЦП А
adc_result=ADCA.CH2.RES;
adc_ptr->Exec(adc_result);
ADCA.CH2.MUXCTRL=adc_ptr->NextMux;
adc_ptr++;

// виртуальный канал 3 АЦП А
adc_result=ADCA.CH3.RES;
adc_ptr->Exec(adc_result);
ADCA.CH3.MUXCTRL=adc_ptr->NextMux;
adc_ptr++;

struct TADC_BChannel *adcb_ptr=(active_block) ? (&AdcB[1][0]) : (&AdcB[0][0]);

// виртуальный канал 1 АЦП B
adc_result=ADCB.CH0.RES;
adcb_ptr->Exec(adc_result);
ADCB.CH0.MUXCTRL=adcb_ptr->NextMux;
adcb_ptr++;

// виртуальный канал 2 АЦП B
adc_result=ADCB.CH1.RES;
adcb_ptr->Exec(adc_result);
ADCB.CH1.MUXCTRL=adcb_ptr->NextMux;
adcb_ptr++;

// виртуальный канал 3 АЦП B
adc_result=ADCB.CH2.RES;
adcb_ptr->Exec(adc_result);
ADCB.CH2.MUXCTRL=adcb_ptr->NextMux;
adcb_ptr++;

// виртуальный канал 4 АЦП B
adc_result=ADCB.CH3.RES;
adcb_ptr->Exec(adc_result);
ADCB.CH3.MUXCTRL=adcb_ptr->NextMux;
adcb_ptr++;

// запуск преобразования
ADC_Conversions_Start(&ADCA, 0xF<<2);
ADC_Conversions_Start(&ADCB, 0xF<<2);

if (++CycleCnt>=16) {
// накоплено 16 отсчётов
CycleCnt=0;
adc_ptr= (active_block) ? (&AdcA[0][0]) : (&AdcA[1][0]);
TADC_AChannel *adc_ptr2= (active_block) ? (&AdcA[1][0]) : (&AdcA[0][0]);
for (char i=0; i<16; i++) {
adc_ptr->Cnt=0;
adc_ptr->Sum=0;
adc_ptr->State=adc_ptr2->State;
adc_ptr++;
adc_ptr2++;
}
adcb_ptr=(active_block) ? (&AdcB[0][0]) : (&AdcB[1][0]);
for (char i=0; i<16; i++) {
adcb_ptr->Sum=0;
}
SumReady=1;
}
}
};



extern TAdc Adc;
void InitADC();

#endif // adc_h__


Прерывание:

Код
TAdc Adc;
ISR(TCC0_OVF_vect)
{
    Adc.StartNextConvervion();
}


IAR выдал код с временем выполнения 450-550 циклов в зависимости от настроек оптимизации, что не есть гуд.
Из интереса создал проект для GCC, проверил в симуляторе ~320-350 тактов (не ожидал такого результата - удивлён).
Как получить от IAR похожий результат?

P.S. Проект сначала не компилился для GCC:
Код
In file included from ../../avr_compiler.h:132:0,
                 from ../task1.cpp:2:
c:\avr_toolchain\bin\../lib/gcc/avr/4.5.1/../../../../avr/include/util/delay.h: In function 'void _delay_ms(double)':
c:\avr_toolchain\bin\../lib/gcc/avr/4.5.1/../../../../avr/include/util/delay.h:149:42: error: 'fabs' was not declared in this scope
c:\avr_toolchain\bin\../lib/gcc/avr/4.5.1/../../../../avr/include/util/delay.h:149:43: error: 'ceil' was not declared in this scope
c:\avr_toolchain\bin\../lib/gcc/avr/4.5.1/../../../../avr/include/util/delay.h: In function 'void _delay_us(double)':
c:\avr_toolchain\bin\../lib/gcc/avr/4.5.1/../../../../avr/include/util/delay.h:226:42: error: 'fabs' was not declared in this scope
c:\avr_toolchain\bin\../lib/gcc/avr/4.5.1/../../../../avr/include/util/delay.h:226:43: error: 'ceil' was not declared in this scope
make: *** [task1.o] Ошибка 1

Что за ...?
Прект:Прикрепленный файл  avr1513.rar ( 313.16 килобайт ) Кол-во скачиваний: 89

Закоментировал delay.h. Тогда откомпилировалось.

Сообщение отредактировал IgorKossak - Feb 1 2012, 07:51
Причина редактирования: [codebox]
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 1 2012, 04:57
Сообщение #2


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(_Артём_ @ Feb 1 2012, 04:02) *
P.S. Проект сначала не компилился для GCC:
Код
In file included from ../../avr_compiler.h:132:0,
                 from ../task1.cpp:2:
c:\avr_toolchain\bin\../lib/gcc/avr/4.5.1/../../../../avr/include/util/delay.h: In function 'void _delay_ms(double)':
c:\avr_toolchain\bin\../lib/gcc/avr/4.5.1/../../../../avr/include/util/delay.h:149:42: error: 'fabs' was not declared in this scope
c:\avr_toolchain\bin\../lib/gcc/avr/4.5.1/../../../../avr/include/util/delay.h:149:43: error: 'ceil' was not declared in this scope
c:\avr_toolchain\bin\../lib/gcc/avr/4.5.1/../../../../avr/include/util/delay.h: In function 'void _delay_us(double)':
c:\avr_toolchain\bin\../lib/gcc/avr/4.5.1/../../../../avr/include/util/delay.h:226:42: error: 'fabs' was not declared in this scope
c:\avr_toolchain\bin\../lib/gcc/avr/4.5.1/../../../../avr/include/util/delay.h:226:43: error: 'ceil' was not declared in this scope
make: *** [task1.o] Ошибка 1

Что за ...?
Прект:Прикрепленный файл  avr1513.rar ( 313.16 килобайт ) Кол-во скачиваний: 89

Закоментировал delay.h. Тогда откомпилировалось.

подключите math.h перед delay.h
- это писатели avr-libc оплошали, ИМХО math.h стоило подключить внутри delay.h.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
follow_me
сообщение Feb 1 2012, 05:05
Сообщение #3


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

Группа: Участник
Сообщений: 182
Регистрация: 4-11-10
Пользователь №: 60 646



похоже что GCC инлайнит
adc_ptr->Exec(adc_result);
а IAR нет

вы игрались с настройками оптимизации компилятора?

должен отметить что код чистенький и ухоженный - многим стоило бы поучиться писать так

единственная придирка - не внятные имена некоторых переменных, а так 5
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Feb 1 2012, 14:14
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(demiurg_spb @ Feb 1 2012, 06:57) *
подключите math.h перед delay.h
- это писатели avr-libc оплошали, ИМХО math.h стоило подключить внутри delay.h.


Да, понятно, оплошали.

Цитата(follow_me @ Feb 1 2012, 07:05) *
похоже что GCC инлайнит
adc_ptr->Exec(adc_result);
а IAR нет

Похоже на то
Забыл inline.
Поставил
Код
#pragma inline=forced
    inline void Exec(unsigned short new_value) {


Стало 360 циклов.
Цитата(follow_me @ Feb 1 2012, 07:05) *
единственная придирка - не внятные имена некоторых переменных, а так 5

Какие имена не очень?

Спасибо.
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Feb 2 2012, 18:28
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Не получается установить оптимизацию. Делаю так (по результату виу что эфекта нет)
Код
#pragma optimize=speed
    Adc.StartNextConvervion();
#pragma optimize=balanced

Как правильно?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 3 2012, 07:04
Сообщение #6


Гуру
******

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



QUOTE (_Артём_ @ Feb 2 2012, 20:28) *
Не получается установить оптимизацию. Делаю так (по результату виу что эфекта нет)
В документации когда-то было упоминание, что эта прагма позволяет лишь понизить уровень оптимизации или вернуть после понижения к исходному.


--------------------
На любой вопрос даю любой ответ
"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
Genadi Zawidowsk...
сообщение Feb 3 2012, 10:22
Сообщение #7


Профессионал
*****

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



А что мешает установиь оптимизацию глобально - в установках проекта? Или работать перестаёт?
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Feb 3 2012, 14:33
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(Genadi Zawidowski @ Feb 3 2012, 12:22) *
А что мешает установиь оптимизацию глобально - в установках проекта? Или работать перестаёт?


Глобально установить можно, работает.
Но если я хочу часть проекта(часть файла в проекте) оптимизировать как balanced, а часть (Adc.StartNextConvervion) по скорости.
Вот и тут мне не ясно, возможно ли прагмами управлять этим процессом и как, если возможно.
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Feb 5 2012, 14:28
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(Сергей Борщ @ Feb 3 2012, 09:04) *
В документации когда-то было упоминание, что эта прагма позволяет лишь понизить уровень оптимизации или вернуть после понижения к исходному.

Тогда получается, что оптимизацию inline-функции можно задать только настройкой оптимизации проекта или файла в котором вызывается функция?
Или есть другие варианты?

Go to the top of the page
 
+Quote Post
sKWO
сообщение Feb 14 2012, 19:01
Сообщение #10


Местный
***

Группа: Участник
Сообщений: 355
Регистрация: 27-03-07
Из: Україна, Чуднів
Пользователь №: 26 530



Цитата(_Артём_ @ Feb 5 2012, 17:28) *
Тогда получается, что оптимизацию inline-функции можно задать только настройкой оптимизации проекта или файла в котором вызывается функция?

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


--------------------
нельзя недооценивать предсказуемость глупости
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Feb 14 2012, 19:06
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(sKWO @ Feb 14 2012, 21:01) *
А оптимизация для всего прожекта задаётся в его настройках и касается всех файлов подклёчённых к нему.

Это для GCC?
В IAR можно задать настройки оптимизации для каждого файла в проекте индивидуально.
Для GCC наверное тоже подобное возможно с помащью редактирования makefile.
Go to the top of the page
 
+Quote Post
sKWO
сообщение Feb 14 2012, 19:44
Сообщение #12


Местный
***

Группа: Участник
Сообщений: 355
Регистрация: 27-03-07
Из: Україна, Чуднів
Пользователь №: 26 530



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


Цитата(_Артём_ @ Feb 2 2012, 21:28) *
Как правильно?

цитата (IAR Compiler reference):
The #pragma directive is defined by the ISO/ANSI C standard and is a
mechanism for using vendor-specific extensions in a controlled way to make
sure that the source code is still portable.
The pragma directives control the behavior of the compiler, for example how
it allocates memory for variables and functions, whether it allows extended
keywords, and whether it outputs warning messages.
The pragma directives are always enabled in the compiler.

...

#pragma optimize=param[, param,...]

param:

s Optimizes for speed
z Optimizes for size
2|none|3|low|6|medium|9|high Specifies the level of optimization

и, ещё ИМХО прагмами играют когда ИАР некоторые функции "заоптимизирувает" как говорится, и когода не помогает волотайл для переменной, тогда играют с понижением оптимизации, потому и результата Вы и не увидели, опять же ИМХО.


--------------------
нельзя недооценивать предсказуемость глупости
Go to the top of the page
 
+Quote Post

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

 


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


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