|
avr-gcc и IAR, сравнение, но не холивар |
|
|
|
Feb 21 2011, 11:11
|

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

|
(Предыстория. Можно пропустить.) Я чуть боле двух лет как перебрался на Линукс. Оставил в покое Венду и Вендовые компиляторы. Все хорошо, полет более чем нормальный. Не сочтите за рекламу! Сижу в Ubuntu (и Debian). Просто после Венды мне показалось, что Ubuntu легче освоить, чем другие Линуксы типа Gentoo и Slackware. Тем более столько народа в ней сидит. И тем более, что средства для разработки программ для AVR уже лежат готовые в репозиториях. В общем, живу и в ус не дую. Но меня давно подмывало произвести ревизию бинарного кода, который компилится avr-gcc, и сравнить его с IAR-овским кодом. Но все как-то не получалось сделать. То проект был не большой (типа "хелловорлд" в исполнении светодиодов), и поэтому полноценного сравнения не могло получиться. То проект наоборот был большой, и не хватало времени на его портацию в другую среду. А то проект коммерческий -- типа нельзя публиковать. В общем, все как-то не стыковалось с моими чаяниями. И вот, внезапно выпало счастье заняться небольшим "не засекреченным" проектом. Я его начинал создавать на Mega48. Но в какой-то момент, по мере его роста не хватило флеши, пришлось перебираться на Mega8. Бывает. Не проблема! Переписал. Все легко поднялось и заработало. И на второе счастье у меня оказались свободными выходные (уже прошедшие). Чем я и воспользовался. Откопал старый винт с установленной Вендой и IAR-ом, подцепил к компу.. и на до же! Оказывается я все еще помню, как в Венде тыкать мышкой! Короче, перенес проект под IAR, скомпилировал и поразился. (А вот теперь по делу.) Понятно, что поскольку компиляторы разные, они и должны создавать разный по объему код. Если размер кода (бинарник) чуть-чуть превышает 4КБ, то, как вы думаете, какая разница будет в объеме сгенерированных компиляторами кодов? Я ожидал получить разницу в размере кода ну 100, ну 200 байт. А получил аж 1200 байт. Солидный кусок! Так сильно gcc меня еще не опускал. Обидно, да-а? Конечно, на мое впечатление еще оказал воздействие тот факт, что если бы я изначально писал под IAR-ом, то мне бы не пришлось по ходу менять проц. Но ведь сам выбрал Линух и gcc! Но это все эмоции. Мне же интересно было разобраться с состоянием дел вообще. Сначала я засел за оптимизацию. Начал перебирать различные комбинации ключей в надежде как можно более сильно сократить код и под gcc, и под IAR-ом. Да. Мне это удалось сделать. Код немного ужался и там, и там, но все равно разница в килобайт с хвостиком сохранилась: один компайлер генерит код размером в 2596 байт, другой -- 3772 байта. Я оцениваю размер кода по hex-файлу, который непосредственно заливается во флешь. Т.е. здесь вообще без дураков, которых можно обмануть не посчитав, допустим, размер таблицы векторов. Или опустив размер вспомогательных (ну или как их правильно-то назвать?) функций, который компилятор сам может создавать, увидев повторяющиеся участки кода. (Вопрос.) Коллеги, не впадая в безумие священных войн, вы можете помочь установить истину в работе компиляторов -- почему они дают такой существенно разный результат? Возможно что-то я не правильно делаю. (А это обязательно так!) Но мне, да и многим из вас, хотелось бы знать -- в каком отношении по объему друг к другу эти компиляторы "готовят" код. Полный код проекта я могу предоставить. Единственная просьба -- по возможно соблюдать одинаковость исходных кодов в обоих версиях (для gcc и для IAR). Ну, например, в gcc я есть команда для запрета прерываний cli(), и в IAR-е она тоже есть -- __disable_inerrupt(). Это все легко соблюсти. Сложнее соблюсти, допустим, программные задержки. В библиотеке gcc есть функции _delay_us() и _delay_ms(), а в IAR-е таковых нет. Но по жизни очень часто бывает так, что эти в программе без задержек никак. Поэтому я допускаю, что в исходниках для IAR-а, будут использованы приемы типа Код #define FCLK (11059200) #define delay_ms(n) __delay_cycles((FCLK / 1000) * (n)); #define delay_us(n) __delay_cycles((FCLK / 1000000) * (n)); Есть еще одно замечание. Исходный текст написан не очень правильно с точки зрения профи. Пока его улучшать не надо! Я поясню. Дело в том, что этот проект не коммерческий, и этот девайс не предполагается кому-то продавать. Кроме того, передо мной стаояла задача: достаточно тупо слепить устройство и установить его в работу, не доводя его до витринного блеска. Поэтому, например, вместо того, чтобы работать с функциями строк из флеша (avr/pgmspace.h), я их тупо прописываю в printf() и не парюсь, что при этом в Оперативе создается их копия. Просто пока не до этого! В общем, давайте _пока_ не будем трогать исходники. Ибо я хочу посмотреть на возможности компиляторов для среднестатистического быдлокодера, который пишет проги вот на таком вот уровне. А когда мы совместными усилиями получим какие-то цифры, для сравнения компиляторов, вот тогда уже можно будет отрываться и пытаться уникальными для конкретного компилятора приемами уменьшить объем кода. Не думайте, что я пытаюсь вашими руками написать свой проект! Проект уже работает и приносит определенную пользу. Дальнейшее улучшение проекта пойдет не по направлению уменьшения кода или вылизыванию в нем ошибок, а по направлению увеличения функциональности (насыщенности). Но даже и это пока не нужно. У меня другая задача -- разобраться с компиляторами. Надеюсь, вы понимаете меня, и топик не съедет в бессмысленный срач. Пожалуйста, задавайте ваши вопросы.
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
 |
Ответов
|
Feb 23 2011, 11:44
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Наткнулся на интересную бяку. Для начала, убрал все "ньюансовые" флаги. Размер существенно не менялся. Компилер, тсз conventional 2010-0110  Придрался к стремно-длинным прологам/эпилогам в прерываниях. По опыту - это гавновопрос, сделал так (почти на автопилоте) Код static void postmessage_prim(msg_t msg); void postmessage(msg_t msg) { postmessage_prim(msg); } Соответственно, в прерываниях, поменял вызовы на статик-примитив. Логика железная - статик как на ладони, шохошь то и делай. Так он, собако, абсолютно это игнорирует и прологи те же.  Вот жеж нанизм блин! И самое загадостное, что у мну это много раз так разруливалось. Он что, фамилию спрашиват? UPD причину нашел, надо было указать __attribute__((pure)) С дефолтовым минимальным принтфом 3788 байт.
|
|
|
|
|
Feb 26 2011, 17:02
|

неотягощённый злом
     
Группа: Свой
Сообщений: 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
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Feb 26 2011, 21:14
|

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

|
Цитата(demiurg_spb @ Feb 26 2011, 22:02)  ... выдал на 30 байт больше 3454 30 байт это 1%. Мне кажется это не существенно. (что-то все еще никак не могу засесть за свою задачу и заменить printf на более "легкие" функции.)
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Mar 1 2011, 02:14
|

Знающий
   
Группа: Свой
Сообщений: 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 байт флеша. Если у вас есть что добавить или опровергнуть, пожалуйста скажите, я же дальнейшие "исследования" в этом направлении прекращаю. Здесь ловить не чего.
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
Сообщений в этой теме
zhevak avr-gcc и IAR Feb 21 2011, 11:11 _Pasha Может быть, может быть...
Код выложите-то? Feb 21 2011, 11:32 zhevak Цитата(_Pasha @ Feb 21 2011, 16:32) Может... Feb 21 2011, 11:46  MrYuran Цитата(zhevak @ Feb 21 2011, 14:46) Венду... Feb 21 2011, 12:08   demiurg_spb Глянул Ваш Makefile - там можно сказать для хороше... Feb 21 2011, 12:56    zhevak Цитата(demiurg_spb @ Feb 21 2011, 17:56) ... Feb 21 2011, 13:33 dimka76 Для корректного сравнения компиляторов не надо пол... Feb 21 2011, 11:44 zhevak Исходники проектов выложил. Движок форума файлы .t... Feb 21 2011, 12:02 MrYuran ЦитатаПонятно, что поскольку компиляторы разные, о... Feb 21 2011, 11:44 neiver IAR и GCC оба хорошие компиляторы, у каждого свои ... Feb 21 2011, 11:46 zhevak В проекте имеется файл hal.c (абстрагирование от а... Feb 21 2011, 13:13 neiver Да, да. Это феерическое растранжирование памяти в ... Feb 21 2011, 13:27 zhevak Цитата(neiver @ Feb 21 2011, 18:27) Решен... Feb 21 2011, 14:05 MrYuran Цитата20e: ff 91 pop r31
210: e... Feb 21 2011, 13:40 neiver Параметры линкера:
-Wl,-u,vfprintf -lprintf_min
дл... Feb 21 2011, 13:57 _Pasha По приведенным фрагментам.
push/pop ld/st - что в ... Feb 21 2011, 14:01 neiver При использовании близких по функциональности верс... Feb 21 2011, 14:14 zhevak в ответ на http://electronix.ru/forum/index.php?sh... Feb 21 2011, 14:40 _Pasha Цитата(zhevak @ Feb 21 2011, 17:40) и?
Н... Feb 21 2011, 14:45 zhevak Как Вы считали? У меня другие цифры.
(87 + 86) * ... Feb 21 2011, 15:18 neiver Думаю, что не на 250 байт, поменьше. Не всегда Lds... Feb 21 2011, 15:30 _Pasha Цитата(zhevak @ Feb 21 2011, 18:18) Как В... Feb 22 2011, 05:35 klen после танцев с бубном получил следующие размеры
... Feb 22 2011, 09:08  zhevak Ну вроде как стало соизмеримо (если не сказать сра... Feb 22 2011, 11:57   klen точно, чистая культура это вмесо printf заглушки. ... Feb 22 2011, 15:27 vitmeat Попробуйте заменить стандартный gcc'ый printf ... Feb 22 2011, 23:46     zhevak Цитата(MrYuran @ Mar 1 2011, 12:27) Зато,... Mar 1 2011, 08:32      zltigo QUOTE (zhevak @ Mar 1 2011, 11:32) исполь... Mar 1 2011, 20:38       zhevak Цитата(zltigo @ Mar 2 2011, 01:38) Вы, на... Mar 1 2011, 22:46        IgorKossak Цитата(zhevak @ Mar 2 2011, 00:46) Э-э...... Mar 2 2011, 09:56         demiurg_spb Наверное можно подвести кое какие итоги.
Я бы хоте... Mar 2 2011, 10:31          zhevak Цитата(demiurg_spb @ Mar 2 2011, 15:31) Н... Mar 2 2011, 10:57           demiurg_spb Пинят и пинать - два разных слова:-)
Поэтому я и п... Mar 2 2011, 11:56            zhevak Цитата(demiurg_spb @ Mar 2 2011, 16:56) П... Mar 2 2011, 14:17             demiurg_spb Я готов потестить под различными версиями gcc.
Воп... Mar 2 2011, 14:50              klen Цитата(demiurg_spb @ Mar 2 2011, 17:50) Я... Mar 2 2011, 22:03               demiurg_spb FreeRTOS и чистый СИ - не понял как мы это сможем ... Mar 3 2011, 09:41                MrYuran Цитата(demiurg_spb @ Mar 3 2011, 12:41) F... Mar 4 2011, 06:42                 demiurg_spb Цитата(MrYuran @ Mar 4 2011, 09:42) Скоре... Mar 4 2011, 10:50                  MrYuran Цитата(demiurg_spb @ Mar 4 2011, 13:50) В... Mar 4 2011, 10:56           MrYuran Цитата(zhevak @ Mar 2 2011, 13:57) Я попы... Mar 2 2011, 11:57    Сергей Борщ Если я правильно помню принцип работы strcpy_P, то... Mar 1 2011, 09:53     Сергей Борщ Взял проект из первого сообщения. Скомпилил со сво... Mar 1 2011, 14:47      MrYuran Цитата(Сергей Борщ @ Mar 1 2011, 17:47) Е... Mar 1 2011, 15:01      zhevak Я не понял. Что, пьянка -- продолжается что ли? (Э... Mar 1 2011, 17:38  _Pasha Цитата(demiurg_spb @ Feb 26 2011, 20:02) ... Mar 1 2011, 06:54   demiurg_spb Цитата(_Pasha @ Mar 1 2011, 09:54) Это да... Mar 1 2011, 13:02 Nixon Возможно вы просто взяли не совсем удачный проект ... Mar 1 2011, 08:58 _Pasha Цитата(Nixon @ Mar 1 2011, 11:58) Возьмит... Mar 1 2011, 10:36 zhevak Цитата(Nixon @ Mar 1 2011, 13:58) Возможн... Mar 1 2011, 14:39 _Pasha Блин, забыли про такую сущность, как Pascal Stang Mar 4 2011, 11:18
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|