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

 
 
4 страниц V  < 1 2 3 4 >  
Reply to this topicStart new topic
> avr-gcc и IAR, сравнение, но не холивар
zhevak
сообщение Feb 21 2011, 14:05
Сообщение #16


Знающий
****

Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065



Цитата(neiver @ Feb 21 2011, 18:27) *
Решение для avr-gcc - не вызывать из обработчиков прерываний функции из других единиц трансляции или использовать inline функции.

да. Хороша мысль. Но не сейчас, а для второй фазы, когда нужно будет оптимизировать код и писать рекомендации для пользователей gcc.

Цитата
Второй пожиратель ресурсов это как уже все догадались функция sprintf. В IAR проекте у вас используется минимальная урезанная версия, в gcc - полная с поддержкой float и чтения параметров из памяти программ.

Точно! И об этом я тоже как-то не додумался, не дошел! В IAR-е тип функций printf (и scanf) задается в Опциях проекта (General Options / Library Options) из выпадающих списков, а вот в опций для gnu-линковщика я не удосужился поискать. Былпа такая светлая мысль, поискать, но утонула среди других вопросов.
(В IAR-e у меня стоял Printf Formatter = Small)

Сейчас попробую нащупать подобную опцию в avr-ld...
Отбой! Пока я писал этот пост, уже опередили http://electronix.ru/forum/index.php?showt...st&p=888593

Откомпилировал с
Да, действительно скидывает 372 байта. Объем кода по avr-size -- 3400 байт (text), в бинарнике под заливку во флешь 0x0DBA байт (= 3514).
У IAR-а бинарник под заливку -- 0x0A32 байт (= 2610)

Все еще много лишних байт (почти 900) надо чем-то объяснять blink.gif


--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
Go to the top of the page
 
+Quote Post
neiver
сообщение Feb 21 2011, 14:14
Сообщение #17


Местный
***

Группа: Участник
Сообщений: 214
Регистрация: 22-03-10
Из: Саратов
Пользователь №: 56 123



При использовании близких по функциональности версий стандартной библиотеки "normal DLIB" в IAR и -lprintf_min в avr-gcc (обе без поддержки float и еще какой-то фигни) размер кода почти сравнялся: IAR - 3614, avr-gcc - 3708 байт. Изначально в проекте IAR-а использовалясь жутко урезанная "CLIB" версия рантайма. В avr-gcc настолько порезанной несоответствующей стандартам, но тем не менее компактной библиотеки нет.
Так вот. А если функции вызываемые из прерываний сделать встраиваемыми, то будет, видимо, паритет.
Go to the top of the page
 
+Quote Post
zhevak
сообщение Feb 21 2011, 14:40
Сообщение #18


Знающий
****

Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065



в ответ на http://electronix.ru/forum/index.php?showt...st&p=888594
Ну вот, посчитал количество команд (считал через $ grep -iw sts *.lst | wc -l и ее модификации для других мнемоник)

Код
command   gcc   IAR
-------   ---   ----
LDS       87    23
STS       86    25
LD        16    24
ST        26    33

05.gif и?


--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Feb 21 2011, 14:45
Сообщение #19


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(zhevak @ Feb 21 2011, 17:40) *
05.gif и?

На 250 байт разницу объяснили. wacko.gif Блин, я ожидал поболее.
Go to the top of the page
 
+Quote Post
zhevak
сообщение Feb 21 2011, 15:18
Сообщение #20


Знающий
****

Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065



Как Вы считали? У меня другие цифры.

(87 + 86) * 4 + (16 + 26) * 2 = 776 байт
(23 + 25) * 4 + (24 + 33) * 2 = 306 байт

разница 470 байт.


--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
Go to the top of the page
 
+Quote Post
neiver
сообщение Feb 21 2011, 15:30
Сообщение #21


Местный
***

Группа: Участник
Сообщений: 214
Регистрация: 22-03-10
Из: Саратов
Пользователь №: 56 123



Думаю, что не на 250 байт, поменьше. Не всегда Lds можно выгодно заменить на Ld/Ldd - адрес-то нужно предварительно загрузить в регистры.
Для 4-х и 2-х байтовых переменных и для структур выгоднее (только по размеру кода, но не по скорости) Ld/Ldd/St/Std использовать. Для однобайтовых - Lds/Sts.
А вообще, IAR более оптимально использует косвенную адресацию со смещением. AVR-GCC приходится явно намекать какую адресацию использовать, например работая с переменной через указатель.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Feb 22 2011, 05:35
Сообщение #22


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(zhevak @ Feb 21 2011, 18:18) *
Как Вы считали?

(87-23)+(86-25)=125 слов, имея ввиду только разницу между нормальными командами и этой, придурошной sm.gif

Цитата(neiver @ Feb 21 2011, 18:30) *
Думаю, что не на 250 байт, поменьше.
А вообще, IAR более оптимально использует косвенную адресацию со смещением. AVR-GCC приходится явно намекать какую адресацию использовать, например работая с переменной через указатель.

Ну, поменьше, это ж на глазок было. Гцц как ни намекай, он иногда в такую бяку сваливается sad.gif, жаждешь от него этих "со смещением", а их все нету. Это РТЛ деревья, видать, по мозгам сильно проехались. Не умеет он по-настоящему юзать три указателя. Еще Гцц не любит действия со старшим битом. Еще... да нафиг! Зато "на переднем крае" всегда.
Go to the top of the page
 
+Quote Post
klen
сообщение Feb 22 2011, 09:08
Сообщение #23


бессмертным стать можно тремя способами
*****

Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912



после танцев с бубном получил следующие размеры

''чистая культура" без использования библиотечных аля printf
text data bss dec hex filename
2714 30 43 2787 ae3 monitor-gcc.elf

максимум что я выжал не выкидывая авторские вызовый sprintf
text data bss dec hex filename
3240 114 43 3397 d45 monitor-gcc.elf

gcc версия 4.6.0 20110127 (experimental) (Klen's GCC package (KGP) for AVR/elf platform)
Go to the top of the page
 
+Quote Post
zhevak
сообщение Feb 22 2011, 11:57
Сообщение #24


Знающий
****

Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065



Ну вроде как стало соизмеримо (если не сказать сравнялось в ноль!):
gcc: 2787(text) + 30(data) = 2817 байт флеши.
IAR: 2596(text) + 221(data) = 2817 байт флеши

Но что значит "без использования"?
Цитата(klen @ Feb 22 2011, 14:08) *
''чистая культура" без использования библиотечных аля printf


Вы вызовы просто закомментировали или сохранили функциональность, заменив их на strcpy() и itoa()?
В исходниках для IAR-а вызовы printf() не удалены и не заменены. Т.е. как бы условия состязания нарушены.

Вчера ночью попробовал postmessage(), которую вызывают оба прерывания, сделать inline -- ни какой реакции sad.gif, как было, так и осталось.

А пока резюме такое (извините, оно получилось несколько персонифицированным конкретно ко мне)
1. Функции printf и их модификации в тулчейне для avr имеют большие размеры, чем в IAR. Поэтому, если стоит вопрос компактности кода, их использования следует избегать.
2. Не забывать, что функции printf имеют несколько реализаций, выбор которых через ключи линковщика -Wl, -u, ...


Ну что, если других предложений нет, тогда переходим к фазе оптимизации два -- оптимизация кода.
Тут я вижу сразу две точки приложения:
1. Заменить вызовы printf() на strcpy(), strcat() и itoa()
2. Сделать по уму, заменить функции работы с оперативой на функции работы с констатами во флеш, т.е. вместо strcat() использовать strcat_P() и т.д.

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

По крайней мере для себя я понял, почему в первом приближении на gcc не достигается компактность кода присущая IAR, и что следует делать, что бы хоть как-то уменьшить размер кода.


ГОСПОДА, СПАСИБО ЗА КОЛЛАБОРАЦИЮ!

Через какое-то время я сообщу, что у меня получилось после реализации фазы два.


--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
Go to the top of the page
 
+Quote Post
klen
сообщение Feb 22 2011, 15:27
Сообщение #25


бессмертным стать можно тремя способами
*****

Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912



точно, чистая культура это вмесо printf заглушки. я это сделал чтоб посмотреть сколько собственного кода пллучится. второй вариант без нарушения функциональности
Go to the top of the page
 
+Quote Post
vitmeat
сообщение Feb 22 2011, 23:46
Сообщение #26





Группа: Участник
Сообщений: 13
Регистрация: 22-01-11
Пользователь №: 62 402



Попробуйте заменить стандартный gcc'ый printf на xprintf от elm-chan'a http://elm-chan.org/fsw/strf/xprintf.html
Эмм... В общем он теперь тоже сишный и большой, раньше был на асме и маленький, аж удивился rolleyes.gif . Но даже сейчас он меньше.
Заменил sprintf на xsprintf без потери функциональности

Из 4 тулчейнов: biggrin.gif

WinAVR -> ( тут еще включен -mint8 и --param inline-call-cost=0 )
Program: 3268 bytes (39.9% Full)
Data: 161 bytes (15.7% Full)

kgp_avr ->
Program: 3402 bytes (41.5% Full)
Data: 161 bytes (15.7% Full)

AVR_Toolchain -> ( тут еще включен -mint8 )
Program: 3366 bytes (41.1% Full)
Data: 161 bytes (15.7% Full)

mhvavrtools ->
Program: 3386 bytes (41.3% Full)
Data: 161 bytes (15.7% Full)

Для стандартной printf у меня получилось: biggrin.gif

WinAVR -> ( тут еще включен -mint8 и --param inline-call-cost=0 )
Program: 3514 bytes (42.9% Full)
Data: 157 bytes (15.3% Full)

kgp_avr ->
Program: 3578 bytes (43.7% Full)
Data: 157 bytes (15.3% Full)

AVR_Toolchain -> ( тут еще включен -mint8 )
Program: 3554 bytes (43.4% Full)
Data: 157 bytes (15.3% Full)

mhvavrtools ->
Program: 3566 bytes (43.5% Full)
Data: 157 bytes (15.3% Full)

WinAVR -> avr-gcc.exe (WinAVR 20100110) 4.3.3
kgp_avr -> avr-gcc.exe (Klen's GCC package (KGP) for AVR/elf platform) 4.6.0 20100725 (experimental)
AVR_Toolchain -> avr-gcc.exe (AVR_Toolchain_3.0_149) 4.4.3
mhvavrtools -> avr-gcc.exe (GCC) 4.5.1
wacko.gifcranky.gif
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Feb 23 2011, 11:44
Сообщение #27


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Наткнулся на интересную бяку. Для начала, убрал все "ньюансовые" флаги. Размер существенно не менялся. Компилер, тсз conventional 2010-0110 sm.gif
Придрался к стремно-длинным прологам/эпилогам в прерываниях. По опыту - это гавновопрос, сделал так (почти на автопилоте)
Код
static void postmessage_prim(msg_t msg);
void postmessage(msg_t msg)
{
postmessage_prim(msg);
}

Соответственно, в прерываниях, поменял вызовы на статик-примитив. Логика железная - статик как на ладони, шохошь то и делай.
Так он, собако, абсолютно это игнорирует и прологи те же. cranky.gif Вот жеж нанизм блин! И самое загадостное, что у мну это много раз так разруливалось. Он что, фамилию спрашиват?

UPD причину нашел, надо было указать __attribute__((pure))
С дефолтовым минимальным принтфом 3788 байт.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 26 2011, 17:02
Сообщение #28


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

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



Цитата(_Pasha @ Feb 23 2011, 14:44) *
С дефолтовым минимальным принтфом 3788 байт.

аналогично, но у меня поменьше вышло 3424
вообще без правки исходников, лишь переписал Makefile.
CODE
avr-gcc (AVR_Toolchain_3.0_149) 4.4.3
Copyright © 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Building project: bin/monitor-gcctest/monitor-gcc.elf

avr-gcc -mmcu=atmega8 -MMD -MP -MF ./bin/monitor-gcctest/monitor-gcc.dep -gdwarf-2 -DF_CPU=4608000UL -Os -pedantic -funsigned-char
-funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -fno-split-wide-types --combine -fwhole-program -ffunction-sections
-fdata-sections -Wl,--relax -ftree-loop-ivcanon -mcall-prologues -fno-tree-scev-cprop -finline-small-functions -fearly-inlining
--param inline-call-cost=2 -finline-limit=65535 -mshort-calls -fno-unit-at-a-time -Wsign-compare -Wa,-adhlns=./bin/monitor-gcctest/monitor-gcc.lst
-std=c99 -I. hal.c app.c lcd4.c main.c --output bin/monitor-gcctest/monitor-gcc.elf -Wl,-Map=./bin/monitor-gcctest/monitor-gcc.map,--cref
-Wl,--gc-section -Wl,-u,vfprintf -lprintf_min

Creating load file for Flash: bin/monitor-gcctest/monitor-gcc.hex
avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature bin/monitor-gcctest/monitor-gcc.elf bin/monitor-gcctest/monitor-gcc.hex

Creating load file for EEPROM: bin/monitor-gcctest/monitor-gcc.eep
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 --no-change-warnings -O ihex bin/monitor-gcctest/monitor-gcc.elf bin/monitor-gcctest/monitor-gcc.eep || exit 0

Creating Extended Listing: bin/monitor-gcctest/monitor-gcc.lss
avr-objdump -h -S bin/monitor-gcctest/monitor-gcc.elf > bin/monitor-gcctest/monitor-gcc.lss

Creating Symbol Table: bin/monitor-gcctest/monitor-gcc.sym
avr-nm -n bin/monitor-gcctest/monitor-gcc.elf > bin/monitor-gcctest/monitor-gcc.sym

Size after:
AVR Memory Usage
----------------
Device: atmega8

Program: 3424 bytes (41.8% Full)
(.text + .data + .bootloader)

Data: 157 bytes (15.3% Full)
(.data + .bss + .noinit)

Последний WinAVR выдал ещё на 4 байта меньше 3420.
avr-gcc (Klen's GCC package (KGP) for AVR/elf platform) 4.6.0 20100725 (experimental) выдал на 30 байт больше 3454

Сообщение отредактировал IgorKossak - Feb 27 2011, 09:45


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
zhevak
сообщение Feb 26 2011, 21:14
Сообщение #29


Знающий
****

Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065



Цитата(demiurg_spb @ Feb 26 2011, 22:02) *
... выдал на 30 байт больше 3454

30 байт это 1%. Мне кажется это не существенно.

(что-то все еще никак не могу засесть за свою задачу и заменить printf на более "легкие" функции.)


--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
Go to the top of the page
 
+Quote Post
zhevak
сообщение Mar 1 2011, 02:14
Сообщение #30


Знающий
****

Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065



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

Я заменил вызовы sprintf() на strcpy_P(). Где -то это оказалось вообще безболезненно (изменения только в файле app.c):
Код
  case MODE_STOP:
//    strcpy(buf0, "    Spectron");
//    strcpy(buf1, " Click for start");
    strcpy_P(buf0, (PGM_P)pgm_read_word(&(str0)));
    strcpy_P(buf1, (PGM_P)pgm_read_word(&(str1)));
    break;


, а где-то сполшной туман (как потом, через полгода буду сам продираться через это код -- типа что этим кодом хотел сделать и почему нужно было так извращаться, почему нельзя было написать сразу ясно-понятно-чисто):
Код
  case MODE_0:
//    sprintf(buf0, "Channel 1:%6lu", uvchannel0);
    strcpy_P(buf0, (PGM_P)pgm_read_word(&(str4)));
    buf0[8] = '1';
    ltoa(uvchannel0, buf3, 10);
    len = strlen(buf3);
    strcpy((buf0 + (16 - len)), buf3);

    buf1[0] = 0x00;
    break;

Вот, при такой замене размер секции text даже увеличился с 3400 до 3456 байт, а размер секции data уменьшился со 114 до 86 байт.

Потом я вынес повторяющиеся участки в отдельную функцию:
Код
void preplcd(char *buf, char ach, long uv)
{
  char buf3[12];
  uint8_t len;

  strcpy_P(buf, (PGM_P)pgm_read_word(&(str4)));
  buf[8] = ach;
  ltoa(uv, buf3, 10);
  len = strlen(buf3);
  strcpy((buf + (16 - len)), buf3);
}

оставив на месте только ее вызов:
Код
//    sprintf(buf0, "Channel 1:%6lu", uvchannel0);
    preplcd(buf0, '1', uvchannel0);    

    buf1[0] = 0x00;
    break;

То размер секции text удалось еще ужать до 3420 байт.

Таким образом, размер бинарного кода для загрузки во флеш сейчас составляет 3506 байт.

Резюме всего исследования будет такое:

IAR по сравнению с gcc создает заметно более компактный код при минимальных усилиях со стороны программиста.

Увы и ах! Я так понимаю, дальнейшие изыскания не приводят к желаемому результату. К сожалению, вынужден признать, что в этот раз gcc "продул" IAR-у. Это вывод №1.

Вывод №2. Замена sprintf на серию функций не дала существенной экономии. На деле даже получился небольшой проигрыш. Но это скорее всего из-за того, что были так же взяты не чистые функции (strcpy), а функции работы с флеш-памятью (strcpy_P). Но так или иначе получается, что раз улучшения нет, то функции printf в libc не такие уж и "раздутые", как казалось ранее. Просто что-то еще улучшить в gcc или libc у их создателей уже не получается. Использовать же printf на практике вполне можно и даже нужно, ибо ясность исходного кода куда более важна, чем экономия 20 байт флеша.

Если у вас есть что добавить или опровергнуть, пожалуйста скажите, я же дальнейшие "исследования" в этом направлении прекращаю. Здесь ловить не чего.


--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
Go to the top of the page
 
+Quote Post

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

 


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


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