|
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() и не парюсь, что при этом в Оперативе создается их копия. Просто пока не до этого! В общем, давайте _пока_ не будем трогать исходники. Ибо я хочу посмотреть на возможности компиляторов для среднестатистического быдлокодера, который пишет проги вот на таком вот уровне. А когда мы совместными усилиями получим какие-то цифры, для сравнения компиляторов, вот тогда уже можно будет отрываться и пытаться уникальными для конкретного компилятора приемами уменьшить объем кода. Не думайте, что я пытаюсь вашими руками написать свой проект! Проект уже работает и приносит определенную пользу. Дальнейшее улучшение проекта пойдет не по направлению уменьшения кода или вылизыванию в нем ошибок, а по направлению увеличения функциональности (насыщенности). Но даже и это пока не нужно. У меня другая задача -- разобраться с компиляторами. Надеюсь, вы понимаете меня, и топик не съедет в бессмысленный срач. Пожалуйста, задавайте ваши вопросы.
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
 |
Ответов
(1 - 55)
|
Feb 21 2011, 11:44
|

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

|
Цитата Понятно, что поскольку компиляторы разные, они и должны создавать разный по объему код. Если размер кода (бинарник) чуть-чуть превышает 4КБ, то, как вы думете, какая разница в объеме сгенерированных компиляторами кодов может оказаться? За AVR не скажу, но в MSPGCC получал при оптимизации -Os разницу примерно 16к->19к, 25к->29к ну или около этого, в пользу IAR. Специально ничего не оптимизировал, поскольку потолок флеша 60к пока достаточно высоко...
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Feb 21 2011, 11:46
|

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

|
Цитата(_Pasha @ Feb 21 2011, 16:32)  Может быть, может быть... Код выложите-то? Да, конечно и с удовольсивием! Если я приаттачу к своим постам заархивированные (.tar.bz2) файлы -- это нормально будет? Вендузятники смогут разарзивировать?
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Feb 21 2011, 12:02
|

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

|
Исходники проектов выложил. Движок форума файлы .tar.bz2 не принял. Пришлось zip-овать. Цитата(dimka76 @ Feb 21 2011, 16:44)  Для корректного сравнения компиляторов не надо пользоваться библиотечными функциями, а у вас есть printf и из-за него сравнение будет не корректным, т.к. будет зависить от степени корявости этих библиотек, а не от особенности компилятора. Ночью уж попробовал. Для простоты, не взирая на то, что проект станет нерабочим, закомментировал все printf-ы (они только в файле app.c ). Объем кода уменьшился, но колоссальная разница осталась.  Понятно, что printf() много съедает, и дешевле обойтись itoa() и строковыми функциями. Цитата(neiver) Вобщем, по-разноу, для одного исходника IAR генерирует более компактный код, для другого GCC. Да-да, я вот и хочу установить хоть какую-нибудь документально подтвержденную зависимость. А то одни разговоры и слухи. Версии компиляторов: [console] alex@zhevak:~$ avr-gcc --version avr-gcc (GCC) 4.3.5 [/console] IAR v.5.11B
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Feb 21 2011, 13:13
|

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

|
В проекте имеется файл hal.c (абстрагирование от аппаратного уровня), в котором определены функции обработчики двух прерываний -- от таймера и от UART-а. CODE // Прерываение случается каждую миллисекунду ISR (USART_RXC_vect) { uint8_t data; uint8_t status;
status = UCSRA; data = UDR; if ((status & (_BV(FE) | _BV(DOR) | _BV(PE))) == 0) // (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN)) == 0) { // Байт принят без апаратных ошибок _pack = data; postmessage((msg_t) MSG_PACK); // Тоби пакет! } else postmessage((msg_t) MSG_BADPACK); // Пакет принят с ошибкой }
// Прерываение случается каждые 10 миллисекунд ISR (TIMER2_COMP_vect) { static uint8_t _timer_200ms; static uint8_t _key_prevstate;
uint8_t key_currstate;
// Таймер 200 мс if (++_timer_200ms >= 20) { _timer_200ms = 0; postmessage(MSG_TIMER200MS); }
// Отработка таймеров if (_timer_buzzer != 0) if (--_timer_buzzer == 0) BUZZER_OFF;
if (_timer_led0 != 0) if (--_timer_led0 == 0) LED0_OFF;
if (_timer_led1 != 0) if (--_timer_led1 == 0) LED1_OFF;
if (_timer_led2 != 0) if (--_timer_led2 == 0) LED2_OFF;
if (_timer_led3 != 0) if (--_timer_led3 == 0) LED3_OFF;
// проверка нажатия кнопки
if ((PINC & _BV(KEY)) == 0) key_currstate = 1; // Кнопка нажата else key_currstate = 0; // Кнопка отпущена
if ((key_currstate == 1) && (_key_prevstate == 0)) postmessage(MSG_KEY); _key_prevstate = key_currstate; } Вот как это сделал gcc: CODE 00000130 <__vector_3>: 130: 1f 92 push r1 132: 0f 92 push r0 134: 0f b6 in r0, 0x3f; 63 136: 0f 92 push r0 138: 11 24 eor r1, r1 13a: 2f 93 push r18 13c: 3f 93 push r19 13e: 4f 93 push r20 140: 5f 93 push r21 142: 6f 93 push r22 144: 7f 93 push r23 146: 8f 93 push r24 148: 9f 93 push r25 14a: af 93 push r26 14c: bf 93 push r27 14e: ef 93 push r30 150: ff 93 push r31 152: 80 91 d3 00 lds r24, 0x00D3 156: 8f 5f subi r24, 0xFF; 255 158: 80 93 d3 00 sts 0x00D3, r24 15c: 84 31 cpi r24, 0x14; 20 15e: 20 f0 brcs .+8 ; 0x168 <__vector_3+0x38> 160: 10 92 d3 00 sts 0x00D3, r1 164: 84 e0 ldi r24, 0x04; 4 166: c8 df rcall .-112; 0xf8 <postmessage> 168: 80 91 e0 00 lds r24, 0x00E0 16c: 88 23 and r24, r24 16e: 51 f0 breq .+20 ; 0x184 <__vector_3+0x54> 170: 80 91 e0 00 lds r24, 0x00E0 174: 81 50 subi r24, 0x01; 1 176: 80 93 e0 00 sts 0x00E0, r24 17a: 80 91 e0 00 lds r24, 0x00E0 17e: 88 23 and r24, r24 180: 09 f4 brne .+2 ; 0x184 <__vector_3+0x54> 182: ad 98 cbi 0x15, 5; 21 184: 80 91 de 00 lds r24, 0x00DE 188: 88 23 and r24, r24 18a: 51 f0 breq .+20 ; 0x1a0 <__vector_3+0x70> 18c: 80 91 de 00 lds r24, 0x00DE 190: 81 50 subi r24, 0x01; 1 192: 80 93 de 00 sts 0x00DE, r24 196: 80 91 de 00 lds r24, 0x00DE 19a: 88 23 and r24, r24 19c: 09 f4 brne .+2 ; 0x1a0 <__vector_3+0x70> 19e: a8 98 cbi 0x15, 0; 21 1a0: 80 91 df 00 lds r24, 0x00DF 1a4: 88 23 and r24, r24 1a6: 51 f0 breq .+20 ; 0x1bc <__vector_3+0x8c> 1a8: 80 91 df 00 lds r24, 0x00DF 1ac: 81 50 subi r24, 0x01; 1 1ae: 80 93 df 00 sts 0x00DF, r24 1b2: 80 91 df 00 lds r24, 0x00DF 1b6: 88 23 and r24, r24 1b8: 09 f4 brne .+2 ; 0x1bc <__vector_3+0x8c> 1ba: a9 98 cbi 0x15, 1; 21 1bc: 80 91 e3 00 lds r24, 0x00E3 1c0: 88 23 and r24, r24 1c2: 51 f0 breq .+20 ; 0x1d8 <__vector_3+0xa8> 1c4: 80 91 e3 00 lds r24, 0x00E3 1c8: 81 50 subi r24, 0x01; 1 1ca: 80 93 e3 00 sts 0x00E3, r24 1ce: 80 91 e3 00 lds r24, 0x00E3 1d2: 88 23 and r24, r24 1d4: 09 f4 brne .+2 ; 0x1d8 <__vector_3+0xa8> 1d6: aa 98 cbi 0x15, 2; 21 1d8: 80 91 e1 00 lds r24, 0x00E1 1dc: 88 23 and r24, r24 1de: 51 f0 breq .+20 ; 0x1f4 <__vector_3+0xc4> 1e0: 80 91 e1 00 lds r24, 0x00E1 1e4: 81 50 subi r24, 0x01; 1 1e6: 80 93 e1 00 sts 0x00E1, r24 1ea: 80 91 e1 00 lds r24, 0x00E1 1ee: 88 23 and r24, r24 1f0: 09 f4 brne .+2 ; 0x1f4 <__vector_3+0xc4> 1f2: ab 98 cbi 0x15, 3; 21 1f4: 9c 9b sbis 0x13, 4; 19 1f6: 02 c0 rjmp .+4 ; 0x1fc <__vector_3+0xcc> 1f8: 80 e0 ldi r24, 0x00; 0 1fa: 07 c0 rjmp .+14 ; 0x20a <__vector_3+0xda> 1fc: 80 91 d2 00 lds r24, 0x00D2 200: 88 23 and r24, r24 202: 11 f4 brne .+4 ; 0x208 <__vector_3+0xd8> 204: 81 e0 ldi r24, 0x01; 1 206: 78 df rcall .-272; 0xf8 <postmessage> 208: 81 e0 ldi r24, 0x01; 1 20a: 80 93 d2 00 sts 0x00D2, r24 20e: ff 91 pop r31 210: ef 91 pop r30 212: bf 91 pop r27 214: af 91 pop r26 216: 9f 91 pop r25 218: 8f 91 pop r24 21a: 7f 91 pop r23 21c: 6f 91 pop r22 21e: 5f 91 pop r21 220: 4f 91 pop r20 222: 3f 91 pop r19 224: 2f 91 pop r18 226: 0f 90 pop r0 228: 0f be out 0x3f, r0; 63 22a: 0f 90 pop r0 22c: 1f 90 pop r1 22e: 18 95 reti
00000230 <__vector_11>: 230: 1f 92 push r1 232: 0f 92 push r0 234: 0f b6 in r0, 0x3f; 63 236: 0f 92 push r0 238: 11 24 eor r1, r1 23a: 2f 93 push r18 23c: 3f 93 push r19 23e: 4f 93 push r20 240: 5f 93 push r21 242: 6f 93 push r22 244: 7f 93 push r23 246: 8f 93 push r24 248: 9f 93 push r25 24a: af 93 push r26 24c: bf 93 push r27 24e: ef 93 push r30 250: ff 93 push r31 252: 8b b1 in r24, 0x0b; 11 254: 9c b1 in r25, 0x0c; 12 256: 8c 71 andi r24, 0x1C; 28 258: 21 f4 brne .+8 ; 0x262 <__vector_11+0x32> 25a: 90 93 e2 00 sts 0x00E2, r25 25e: 82 e0 ldi r24, 0x02; 2 260: 01 c0 rjmp .+2 ; 0x264 <__vector_11+0x34> 262: 83 e0 ldi r24, 0x03; 3 264: 49 df rcall .-366; 0xf8 <postmessage> 266: ff 91 pop r31 268: ef 91 pop r30 26a: bf 91 pop r27 26c: af 91 pop r26 26e: 9f 91 pop r25 270: 8f 91 pop r24 272: 7f 91 pop r23 274: 6f 91 pop r22 276: 5f 91 pop r21 278: 4f 91 pop r20 27a: 3f 91 pop r19 27c: 2f 91 pop r18 27e: 0f 90 pop r0 280: 0f be out 0x3f, r0; 63 282: 0f 90 pop r0 284: 1f 90 pop r1 286: 18 95 reti А вот так отработал IAR: CODE 26 __interrupt void _usart_rxc_isr(void)
\ _usart_rxc_isr:
27 {
\ 00000000 .... RCALL ?Subroutine0
\ ??CrossCallReturnLabel_0:
\ 00000002 B78F IN R24, 0x3F
28 uint8_t data;
29 uint8_t status;
30
31 status = UCSRA;
\ 00000004 B10B IN R16, 0x0B
32 data = UDR;
\ 00000006 B11C IN R17, 0x0C
33 if ((status & (_BV(FE) | _BV(DOR) | _BV(PE))) == 0) // (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN)) == 0)
\ 00000008 710C ANDI R16, 0x1C
\ 0000000A F421 BRNE ??_usart_rxc_isr_0
34 {
35 // Байт принят без апаратных ошибок
36 _pack = data;
\ 0000000C 9310.... STS _pack, R17
37 postmessage((msg_t) MSG_PACK); // Тоби пакет!
\ 00000010 E002 LDI R16, 2
\ 00000012 C001 RJMP ??_usart_rxc_isr_1
38 }
39 else
40 postmessage((msg_t) MSG_BADPACK); // Пакет принят с ошибкой
\ ??_usart_rxc_isr_0:
\ 00000014 E003 LDI R16, 3
\ ??_usart_rxc_isr_1:
\ 00000016 .... RCALL postmessage
41 }
\ 00000018 BF8F OUT 0x3F, R24
\ 0000001A .... RCALL ?Subroutine1
\ ??CrossCallReturnLabel_2:
\ 0000001C 9518 RETI
\ 0000001E REQUIRE _A_UCSRA
\ 0000001E REQUIRE _A_UDR
\ In segment CODE, align 2, keep-with-next
\ ?Subroutine1:
\ 00000000 9109 LD R16, Y+
\ 00000002 9119 LD R17, Y+
\ 00000004 9129 LD R18, Y+
\ 00000006 9139 LD R19, Y+
\ 00000008 9149 LD R20, Y+
\ 0000000A 9159 LD R21, Y+
\ 0000000C 9169 LD R22, Y+
\ 0000000E 9179 LD R23, Y+
\ 00000010 9009 LD R0, Y+
\ 00000012 9019 LD R1, Y+
\ 00000014 9029 LD R2, Y+
\ 00000016 9039 LD R3, Y+
\ 00000018 91E9 LD R30, Y+
\ 0000001A 91F9 LD R31, Y+
\ 0000001C 9189 LD R24, Y+
\ 0000001E 9508 RET
\ In segment CODE, align 2, keep-with-next
\ ?Subroutine0:
\ 00000000 938A ST -Y, R24
\ 00000002 93FA ST -Y, R31
\ 00000004 93EA ST -Y, R30
\ 00000006 923A ST -Y, R3
\ 00000008 922A ST -Y, R2
\ 0000000A 921A ST -Y, R1
\ 0000000C 920A ST -Y, R0
\ 0000000E 937A ST -Y, R23
\ 00000010 936A ST -Y, R22
\ 00000012 935A ST -Y, R21
\ 00000014 934A ST -Y, R20
\ 00000016 933A ST -Y, R19
\ 00000018 932A ST -Y, R18
\ 0000001A 931A ST -Y, R17
\ 0000001C 930A ST -Y, R16
\ 0000001E 9508 RET
42
43
44 // Прерываение случается каждые 10 миллисекунд
45 // ISR (TIMER2_COMP_vect)
46 #pragma vector = TIMER2_COMP_vect
\ In segment CODE, align 2, keep-with-next
47 __interrupt void _timer2_comp_isr(void)
\ _timer2_comp_isr:
48 {
\ 00000000 939A ST -Y, R25
\ 00000002 .... RCALL ?Subroutine0
\ ??CrossCallReturnLabel_1:
\ 00000004 B79F IN R25, 0x3F
49 static uint8_t _timer_200ms;
50 static uint8_t _key_prevstate;
51
52 uint8_t key_currstate;
53
54 // Таймер 200 мс
55 if (++_timer_200ms >= 20)
\ 00000006 .... LDI R30, LOW(_timer_led0)
\ 00000008 .... LDI R31, (_timer_led0) >> 8
\ 0000000A 8105 LDD R16, Z+5
\ 0000000C 9503 INC R16
\ 0000000E 8305 STD Z+5, R16
\ 00000010 3104 CPI R16, 20
\ 00000012 F020 BRCS ??_timer2_comp_isr_0
56 {
57 _timer_200ms = 0;
\ 00000014 E000 LDI R16, 0
\ 00000016 8305 STD Z+5, R16
58 postmessage(MSG_TIMER200MS);
\ 00000018 E004 LDI R16, 4
\ 0000001A .... RCALL postmessage
59 }
60
61 // Отработка таймеров
62 if (_timer_buzzer != 0)
\ ??_timer2_comp_isr_0:
\ 0000001C 9100.... LDS R16, (_timer_led0 + 4)
\ 00000020 2300 TST R16
\ 00000022 F039 BREQ ??_timer2_comp_isr_1
63 if (--_timer_buzzer == 0)
\ 00000024 9100.... LDS R16, (_timer_led0 + 4)
\ 00000028 950A DEC R16
\ 0000002A 9300.... STS (_timer_led0 + 4), R16
\ 0000002E F409 BRNE ??_timer2_comp_isr_1
64 BUZZER_OFF;
\ 00000030 98AD CBI 0x15, 0x05
65
66 if (_timer_led0 != 0)
\ ??_timer2_comp_isr_1:
\ 00000032 9100.... LDS R16, _timer_led0
\ 00000036 2300 TST R16
\ 00000038 F039 BREQ ??_timer2_comp_isr_2
67 if (--_timer_led0 == 0)
\ 0000003A 9100.... LDS R16, _timer_led0
\ 0000003E 950A DEC R16
\ 00000040 9300.... STS _timer_led0, R16
\ 00000044 F409 BRNE ??_timer2_comp_isr_2
68 LED0_OFF;
\ 00000046 98A8 CBI 0x15, 0x00
69
70 if (_timer_led1 != 0)
\ ??_timer2_comp_isr_2:
\ 00000048 9100.... LDS R16, (_timer_led0 + 1)
\ 0000004C 2300 TST R16
\ 0000004E F039 BREQ ??_timer2_comp_isr_3
71 if (--_timer_led1 == 0)
\ 00000050 9100.... LDS R16, (_timer_led0 + 1)
\ 00000054 950A DEC R16
\ 00000056 9300.... STS (_timer_led0 + 1), R16
\ 0000005A F409 BRNE ??_timer2_comp_isr_3
72 LED1_OFF;
\ 0000005C 98A9 CBI 0x15, 0x01
73
74 if (_timer_led2 != 0)
\ ??_timer2_comp_isr_3:
\ 0000005E 9100.... LDS R16, (_timer_led0 + 2)
\ 00000062 2300 TST R16
\ 00000064 F039 BREQ ??_timer2_comp_isr_4
75 if (--_timer_led2 == 0)
\ 00000066 9100.... LDS R16, (_timer_led0 + 2)
\ 0000006A 950A DEC R16
\ 0000006C 9300.... STS (_timer_led0 + 2), R16
\ 00000070 F409 BRNE ??_timer2_comp_isr_4
76 LED2_OFF;
\ 00000072 98AA CBI 0x15, 0x02
77
78 if (_timer_led3 != 0)
\ ??_timer2_comp_isr_4:
\ 00000074 9100.... LDS R16, (_timer_led0 + 3)
\ 00000078 2300 TST R16
\ 0000007A F039 BREQ ??_timer2_comp_isr_5
79 if (--_timer_led3 == 0)
\ 0000007C 9100.... LDS R16, (_timer_led0 + 3)
\ 00000080 950A DEC R16
\ 00000082 9300.... STS (_timer_led0 + 3), R16
\ 00000086 F409 BRNE ??_timer2_comp_isr_5
80 LED3_OFF;
\ 00000088 98AB CBI 0x15, 0x03
81
82 // проверка нажатия кнопки
83
84 if ((PINC & _BV(KEY)) == 0)
85 key_currstate = 1; // Кнопка нажата
\ ??_timer2_comp_isr_5:
\ 0000008A 999C SBIC 0x13, 0x04
\ 0000008C C002 RJMP ??_timer2_comp_isr_6
\ 0000008E E001 LDI R16, 1
\ 00000090 C001 RJMP ??_timer2_comp_isr_7
\ ??_timer2_comp_isr_6:
\ 00000092 E000 LDI R16, 0
\ ??_timer2_comp_isr_7:
\ 00000094 2F80 MOV R24, R16
86 else
87 key_currstate = 0; // Кнопка отпущена
88
89 if ((key_currstate == 1) && (_key_prevstate == 0))
\ 00000096 3001 CPI R16, 1
\ 00000098 F431 BRNE ??_timer2_comp_isr_8
\ 0000009A 9100.... LDS R16, (_timer_led0 + 6)
\ 0000009E 2300 TST R16
\ 000000A0 F411 BRNE ??_timer2_comp_isr_8
90 postmessage(MSG_KEY);
\ 000000A2 E001 LDI R16, 1
\ 000000A4 .... RCALL postmessage
91 _key_prevstate = key_currstate;
\ ??_timer2_comp_isr_8:
\ 000000A6 9380.... STS (_timer_led0 + 6), R24
92 }
\ 000000AA BF9F OUT 0x3F, R25
\ 000000AC .... RCALL ?Subroutine1
\ ??CrossCallReturnLabel_3:
\ 000000AE 9199 LD R25, Y+
\ 000000B0 9518 RETI
\ 000000B2 REQUIRE _A_PINC
\ 000000B2 REQUIRE _A_PORTC
93 Фейерическое растранжиривание памяти компилятором gcc видите? Что-нибудь можно предпринять на уровне компилятора или для gcc это фатально?
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Feb 21 2011, 13:33
|

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

|
Цитата(demiurg_spb @ Feb 21 2011, 17:56)  Глянул Ваш Makefile - там можно сказать для хорошей оптимизации по объёму сделано далеко не всё. Сейчас нет времени, но вечерком может попробую ваши исходники сбилдить по моим рецептам:-) О результатах отпишусь. Я не помню в каком состоянии оставил Makefile. Я уже отчаялся, добиться от gcc чего-либо значимого, и тупо, просто тупо, как китаес, перебирал варианты. Потом плюнул на все и пошел спать. А сегодня решил обратиться к помощи зала  Да, и это... Makefile это рабочая лошадка, т.е. он постоянно у меня в движении находится. Ну, т.е. это не готовый к употреблению файл. Исходнные тексты я более-иене причесал, а Makefile -- as is. И тем не менее, спасибо за коллаборацию! Жду результатов. Плюс-минус 10-20 байтов особой погоды не делают. Мне хотелось бы скинуть хотя бы 500 байт. Я уж не говорю о килобайте! Но обязательно, я еще раз подчеркиваю, -- сохранить этот быдлокод с его библиотечными вызовами монструозных функций типа printf. Мне хотелось бы в результате нашего совместного поиска выработать какие-то предложения (или правила), как надо и как не надо кодить в gcc. Что допустимо, а что не допустимо в нем по сравнению с IAR.
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Feb 21 2011, 13:40
|

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

|
Цитата 20e: ff 91 pop r31 210: ef 91 pop r30 212: bf 91 pop r27 214: af 91 pop r26 216: 9f 91 pop r25 218: 8f 91 pop r24 21a: 7f 91 pop r23 21c: 6f 91 pop r22 21e: 5f 91 pop r21 220: 4f 91 pop r20 222: 3f 91 pop r19 224: 2f 91 pop r18 226: 0f 90 pop r0 228: 0f be out 0x3f, r0; 63 22a: 0f 90 pop r0 22c: 1f 90 pop r1 22e: 18 95 reti Эта жесть! Копайте в сторону инлайнов Все ваши hal-функции должны быть static inline (извините, ваши исходники не смотрел, меня за свои скоро расстреляют) /Блин, а я-то 4-кратный push/pop в прерываниях считал диким оверхедом/ Цитата(zhevak @ Feb 21 2011, 16:13)  Извините, не знаю как подвернуть эти листинги-простыни. Наверняка же можно как-то cut-нуть. Подскажите, плиз! тег CODEBOX. Поправьте вручную или слева вверху есть пулл-даун "Спец.элементы"
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Feb 21 2011, 14:05
|

Знающий
   
Группа: Свой
Сообщений: 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) надо чем-то объяснять
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Feb 21 2011, 14:40
|

Знающий
   
Группа: Свой
Сообщений: 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  и?
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Feb 22 2011, 05:35
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(zhevak @ Feb 21 2011, 18:18)  Как Вы считали? (87-23)+(86-25)=125 слов, имея ввиду только разницу между нормальными командами и этой, придурошной  Цитата(neiver @ Feb 21 2011, 18:30)  Думаю, что не на 250 байт, поменьше. А вообще, IAR более оптимально использует косвенную адресацию со смещением. AVR-GCC приходится явно намекать какую адресацию использовать, например работая с переменной через указатель. Ну, поменьше, это ж на глазок было. Гцц как ни намекай, он иногда в такую бяку сваливается  , жаждешь от него этих "со смещением", а их все нету. Это РТЛ деревья, видать, по мозгам сильно проехались. Не умеет он по-настоящему юзать три указателя. Еще Гцц не любит действия со старшим битом. Еще... да нафиг! Зато "на переднем крае" всегда.
|
|
|
|
|
Feb 22 2011, 11:57
|

Знающий
   
Группа: Свой
Сообщений: 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 -- ни какой реакции  , как было, так и осталось. А пока резюме такое (извините, оно получилось несколько персонифицированным конкретно ко мне) 1. Функции printf и их модификации в тулчейне для avr имеют большие размеры, чем в IAR. Поэтому, если стоит вопрос компактности кода, их использования следует избегать. 2. Не забывать, что функции printf имеют несколько реализаций, выбор которых через ключи линковщика -Wl, -u, ... Ну что, если других предложений нет, тогда переходим к фазе оптимизации два -- оптимизация кода. Тут я вижу сразу две точки приложения: 1. Заменить вызовы printf() на strcpy(), strcat() и itoa() 2. Сделать по уму, заменить функции работы с оперативой на функции работы с констатами во флеш, т.е. вместо strcat() использовать strcat_P() и т.д. Ну вот пожалуй это все, что я вижу, что можно сделать, чтобы легко выдавить из gcc. Давить наверняка можно еще, но это уже будет сродни национальным танцам народов севера с использованием ударных музыкальных инструментов. По крайней мере для себя я понял, почему в первом приближении на gcc не достигается компактность кода присущая IAR, и что следует делать, что бы хоть как-то уменьшить размер кода. ГОСПОДА, СПАСИБО ЗА КОЛЛАБОРАЦИЮ! Через какое-то время я сообщу, что у меня получилось после реализации фазы два.
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Feb 22 2011, 23:46
|
Группа: Участник
Сообщений: 13
Регистрация: 22-01-11
Пользователь №: 62 402

|
Попробуйте заменить стандартный gcc'ый printf на xprintf от elm-chan'a http://elm-chan.org/fsw/strf/xprintf.htmlЭмм... В общем он теперь тоже сишный и большой, раньше был на асме и маленький, аж удивился  . Но даже сейчас он меньше. Заменил sprintf на xsprintf без потери функциональности Из 4 тулчейнов: 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 у меня получилось: 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 
|
|
|
|
|
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 байт флеша. Если у вас есть что добавить или опровергнуть, пожалуйста скажите, я же дальнейшие "исследования" в этом направлении прекращаю. Здесь ловить не чего.
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Mar 1 2011, 08:32
|

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

|
Цитата(MrYuran @ Mar 1 2011, 12:27)  Зато, по соотношению цена/качество GCC на недосягаемой высоте  Ну, а если надо в считанные килобайты упихивать, то может, лучше вообще от си отказаться. Есть, например, очень компактные форт-машины. Ну, это уже холивар, от которого я бы хотел отойти. Мне важно не поспорить, а важно найти истину -- важно знать, что и сколько я (лично я) теряю при использовании gcc. А то, что gcc распространяется бесплатно, так это итак все знают. Но сколько при этом теряется "компактности" -- одни слухи и какие-то бездоказательные утверждения. Я, так сказать, пожертвовал своим временем и своей репутацией (вывесил сушиться свои трусы на площади). Я думаю, что народ понял мой поступок, поэтому давайте по существу. Иначе мы так и будем продолжать жить эмоциями, а не фактами. Уйти разработчику на ассемблер или на форт -- да, наверно это можно. Но хотелось бы не менять условий, хотелось сравнить два компилятора в примерно одинаковых условиях. Если Вас, MrYuran, это хоть как-то успокоит, то знайте, что я сожалею о "проигрыше" gcc, но тем не менее, остаюсь с ним. Как я уже где-то выше говорил, я не использую Венду вообще. Поэтому у меня нет выбора. И даже если бы сидал под Вендой, то использовать пиратский IAR мне претит мое воспитание. И тут дело даже не в неотвратимости наказания за пиратство. Тут более высокие понятия. Дети будут ржать, но все же скажу -- дело в морали. Дело в ответе на тот самый главный вопрос -- а для чего мы вообще живем. Каждым человеком движет получение удовольствия. Мы все получаем удовольствие. Только один получает удовольствие от того, что имеет много денег, а другой -- от того, что много знает и много чего умеет делать. Мне нравиться второе. Плюс, я еще это положение "дожимаю" понятиям типа "жить, оставаясь в рамках морали". (Не в рамках закона, а по совести -- почувствуйте разницу!) Мне это интересно, и я от этого получаю удовольствие. А деньги -- что! Деньги -- фигня! Сколько бы их ни было, их всегда не хватает. Определитесь со своим главным вопросом, и все придет в норму. Я никого не осуждаю. Просто каждый сам отвечает на это вопрос по-своему, а как правильно -- никто не знает. Блин. На хрена я это все написал? Ладно. Пусть будет. Может сгодится кому еще.
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Mar 1 2011, 09:53
|

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

|
Если я правильно помню принцип работы strcpy_P, то надо делать проще: strcpy_P(buf0, str0); Не нужно читать первые два байта строки и пытаться трактовать их как адрес. Можно более красиво (если строки уникальные и не С++): strcpy_P(buf0, PSTR(" Spectron"));
А если речь уже зашла об "оптимизируем исходник, оставляя неизменной функциональность", то как минимум в дисплее можно наэкономить отказавшись от чтения готовности, от операции %20, объединив -wrc и LCD_char(). В общем "из любой программы можно выжать еще хотя бы один байтик".
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Mar 1 2011, 13:02
|

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

|
Цитата(_Pasha @ Mar 1 2011, 09:54)  Это да, убийственные ключики  Только напрягает, что надо все за один пасс делать... Меня не напрягает вовсе. У меня вообще все проекты для младших AVR (до Mega162 включительно) только благодаря этому и влезают в кристалл. Да ещё и бутлоадер.... 2ТС:Давайте потестируем на каком-нибудь опенсорсном проекте для AVR размером от 40КБ...
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Mar 1 2011, 14:39
|

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

|
Цитата(Nixon @ Mar 1 2011, 13:58)  Возможно вы просто взяли не совсем удачный проект для сравнения, слишком маленький, на котором оверхед GCC выражается в разы. Вот и получилось как в рекламных пресс-релизах. Возьмите проект посерьезнее или даже несколько, разных размеров. Это будет и позновательнее и объективнее. Да. Спасибо. Я взял то, что смог окучить. Точнее -- почти окучил (т.е. имеются траблы, читайте ниже ответ Сергею). Ведь помимо этой работы -- переноса проекта в другую среду, сравнения и разборки чего-там можно отпилить еще, есть и основная работа. У Вас есть время? Вот и у меня так же. А на счет объективности... ну-у, небольшие проекты тоже имеют право на жизнь. А будет большой проект, и будет достаточно времени, обязательно попробую. Только ведь это...  наши желания редко согласуются с программой Всевышнего. Цитата(Сергей Борщ @ Mar 1 2011, 14:53)  Если я правильно помню принцип работы strcpy_P, то надо делать проще: strcpy_P(buf0, str0); Не нужно читать первые два байта строки и пытаться трактовать их как адрес. Можно более красиво (если строки уникальные и не С++): strcpy_P(buf0, PSTR(" Spectron"));
А если речь уже зашла об "оптимизируем исходник, оставляя неизменной функциональность", то как минимум в дисплее можно наэкономить отказавшись от чтения готовности, от операции %20, объединив -wrc и LCD_char(). В общем "из любой программы можно выжать еще хотя бы один байтик". А-а, блин!!! Спасибо, Сергей! Конечно же нужно так: Код strcpy_P(buf, str4); Все спешим, спешим...Это ж ведь уже готовые строки. Вот так и живем, не приходя в сознание! На удивление, размер кода еще ужался, значит компилятор что-то там преобразовывал. Кому интересно, сейчас text = 3408 байт. (Результаты последних компиляций я не проверял. Железка на полигоне. Мониторит процессы. Отключать, снимать не желательно. Второго экземпляра нет.)
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Mar 1 2011, 14:47
|

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

|
Взял проект из первого сообщения. Скомпилил со своим makefile, WinAVR 20100110, 3910 байт program, 157 data. Переработал lcd.c (убрал чтение готовности, объединил вывод команд и символов, переписал SetXY, 4 строки): 3750 байт hal.c: Добавил inline - 3738 app.c: Объявил uvchannel массивом, свернул в цикл обработку в procpack: - 3620 app.c: сделал обнуление uvchannel через memset : 3566 app.c: static inline procpack: 3554 app.c: static inline update_lcd: 3544 makefile: -lprintf_min: 3172 lcd.c: сделал 2 строки в SetXY: 3156 app.c: заменил sprintf на strcpy_P, sprintf_P - 3134 / 47 data app.c: вынес из switch buf1[0] = '\0' - 3124 увеличил --param inline-call-cost до 2 - 3120. Результат в приложении. ой, ошибочку внес. После переделки на sprintf_P уже нельзя делать buf1[0] = '\0'; сейчас исправлю. Нет, можно. Все нормально.
zhevak_test_gcc.zip ( 10.25 килобайт )
Кол-во скачиваний: 88Если однократно вызываемые функции повыностить из .c в .h и сделать их static inline - можно выиграть еще.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Mar 1 2011, 17:38
|

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

|
Я не понял. Что, пьянка -- продолжается что ли? (Эт-зря я уснул в слате. Рановато получилось.) Цитата(Сергей Борщ @ Mar 1 2011, 19:47)  Взял проект из первого сообщения... Сергей, отличная работа! А Вы можете теперь проделать примерно тоже самое в IAR-e? ... и за одно учесть мнение MrYuran на счет inline.
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Mar 1 2011, 22:46
|

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

|
Цитата(zltigo @ Mar 2 2011, 01:38)  Вы, наверное, не поверите, но IAR можно купить. Не всегда стоит экономить на инструментах. Заодно не придется юродски коверкать названия продуктов. Вы, наверное, не поверите, но gcc распространяется бесплатно. Не всегда стоит покупать то, чему есть достойные альтернативы, удовлетворяющие вашим потребностям. Все это вопросы философии. Не имеет смысла спорить. Цитата Заодно не придется юродски коверкать названия продуктов. Э-э... извините, вот тут я вообще ничего не понял. Это Вы про что?
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Mar 2 2011, 10:57
|

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

|
Цитата(demiurg_spb @ Mar 2 2011, 15:31)  Наверное можно подвести кое какие итоги. Я бы хотел заострить внимание на том, что прежде чем пинять на тот или иной продукт стоит его изучить и поработать в нём какое-то время. И второе но не менее важное - без хорошего знания языка программирования грешить на объём прошивки как минимум неразумно (камень в огород ТС). Компиляторы нынче весьма умные (что IAR что gcc оба достойные конкуренты друг-другу), но программист - это всё же определяющий фактор. Пусть звучит банально, но зато отражает моё личное отношение к теме. Спасибо за критику. Пинать продукты? Да, собственно, никто и не думал пинать. Есть исходный текст проекта, который реальный, а не гипотетический. Не идеальный (а что, разве в жизни все проекты идеальные?) На этом проекте мы поигрались. Получили какой-то результат. Я вообще не вижу никаких проблем. Единственная проблема состоит в том, что я захотел самостоятельно на своем проекте убедиться для себя лично кое-в-каких цифрах. Да, я и не говорю, что я очень хорошо знаю язык, среду разработки и прочее, что влияет на объем и качество кода. Знаю их на каком-то своем уровне. Этот уровень меня минимально устраивает. Я делаю свою работу и как могу повышаю свою квалификацию. Это плохо? Ну, ладно, я не подходящая кандидатура. Давайте тогда что-ли найдем идеального товарища, который согласится оставить свою работу, провести всестороннее исследование и ответить на множество вопросов. Но ведь таких людей нет! Они заняты решением своих проблем. Вот, например, товарищ A (не буду называть его имя) -- грамотный специалист. Давайте его поспрашиваем. Что мы получим? Вместо ответов мы нарвемся на наезды, что мы делаем не то и не так, и вообще не тем занимаемся. Мы о себе много чего узнаем интересного. Но ответ на вопрос -- это уж как товарищ решит, можем и не получить. Я попытался "испечь торт" из того, что у меня было. Вам не понравилось? Ну что ж... Хорошо. Вы можете чем-то помочь? Блин, все-таки холливар! Словоблудие.
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Mar 2 2011, 11:57
|

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

|
Цитата(zhevak @ Mar 2 2011, 13:57)  Я попытался "испечь торт" из того, что у меня было. Вам не понравилось? Ну что ж... Хорошо. Вы можете чем-то помочь? Да всё нормально. Я год назад сделал примерно такой же вывод - что IAR обеспечивает как минимум не худший вариант при значительно меньших усилиях и знаниях. Ну, на то и коммерческий продукт, должен же он хоть чем-то отличаться от свободного  . Осознав данный факт, я решил больше не дёргаться по этому поводу и оптимизировать проект только в случае действительной необходимости (не лезет или не успевает) Ещё, в MSPGCC остановились в своё время на версии GCC 3.2.3, потом родился параллельный проект с GCC 4xx. Так вот, сравнение по объёму далеко не в пользу последнего, даже со всеми дополнительными ухищрениями. А WinAVR собирается как раз на основе свежих версий GCC.
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Mar 2 2011, 14:17
|

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

|
Цитата(demiurg_spb @ Mar 2 2011, 16:56)  Пинят и пинать - два разных слова:-) Поэтому я и предлагал использовать приличный во всех смыслах open-sourсe проект для таких вот изысканий. Или даже больше какой-либо синтетический тест из уже существующих. Изобретение колеса заново - не метод инженера. Ну, тогда уж не "пинять" а, "п енять". Извините, я действительно не знал, как понимать Ваши слова. Ну, давайте, давайте возьмем готовый opensource-проект. Лично я не против. Другие участники, думаю, тоже не будут возражать. Вопрос только в том, кто все это будет делать? Кто все это дело будет двигать? Я не смогу. Вы предложили -- Вы и раскручивайте кампанию, а мы по мере сил Вам поможем и, уж простите, так повелось, -- покритикуем. Ну что, беретесь? Только я буду на вторых ролях, не хочу быть лидером. MrYuran, да я такого же мнения. Жить с gcc можно. Хотя, признаться, я несколько разочарован, но ведь не смертельно ж! Тем более, что Заказчику как правило, вообще пофиг на чем написано -- хоть на Васике! Лишь бы работало согласно ТЗ, и стоимость разработки не вылезала за бюджет.
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Mar 2 2011, 22:03
|

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

|
Цитата(demiurg_spb @ Mar 2 2011, 17:50)  Я готов потестить под различными версиями gcc. .... а как я готов!!! готовее меня есть кто ??  предлагаю архитектуру проекта. 0. используем компонентный подход 1. проект представляет собой основной модуль - FreeRTOS 2. далее модули, реализующие часто встречающиеся или не часто задачи из предметной области оформленные в виде библиотек, юзабельные в тестовых задачах FreeRTOS, 3, две версии - одна чистый С, вторая версия смесь С/С++/Fortran пережовывемые компиллеров в едином сборочном проъекте. что нам это даст. 0.модульность и взаимозаменяймость. 1, при желании практически полную независимость модулй 2, возможность набирать тестовый набор модулей наиболее соответствующему требуемому испытанию. 3, простата измерения размера модулей(возможно напишу утилсу которая лазит по elf и считает то что нужно по отдельности) и их скорости на контрольной трассе (средствами FreeRTOS). 4. комплексная оценка совместной работы с другими модулями и FreeRTOS. что имею. 0, Шаблон проекта посторенного по вышеописанному 1, готове модули а) решение системы нелинейных уравнений на С б) модуль на Фортране реализующий ЧМ демодулятор комплексного сигнала на нулевой промежутке. в) хороший такой тест шаблонов STL на С++. кстате сам удивился когда оказалось что можно эффективно использовать на микроконтроллерах. г) могу сделать страницу на своем портале посвещенную всему этому театральному действу, сделать SVN репозиторий для проекта, раздать права на запись наиболее горячмим джигитам, права на чтения "бесплатно" ну вот както так. ессесено все это борахло будет компилятся для avr и arm. я собсно кортексы в хвост и гриву ..... оттестю. мой мотив проистекает из интереса к скорости генерируемого кода - всегда борюсь за наносекунды, за десятки байтов както не приходилось - ниразу не смог написать столько кода чтоб невлазило, обысно грамотное проектирование в мозгу и на доске с мелом в виде схем ужимает код лучше любого компиллера. хотелось бы чтоб тема не заглохла а превратилась в феерическое представлнеие траха мозка и отжига - нада ж както отдыхать ....
|
|
|
|
|
Mar 3 2011, 09:41
|

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

|
FreeRTOS и чистый СИ - не понял как мы это сможем сбилдить с ключиками --combine -fwhole-program, раз уж мы хотим выжать из gcc по максимуму ...Какие-либо "относительно стандартные" тесты существуют? Предлагаю из модулей подцепить: free-modbus fatfs и какую-нибудь GUI-библиотечку. насчёт SVN - одобрям
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Mar 4 2011, 10:50
|

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

|
Цитата(MrYuran @ Mar 4 2011, 09:42)  Скорее наоборот, с плюсами проблемы будут, FreeRTOS на чистом си написан от ScmRtos навелось... Цитата Сишные исходники скомпилить оптом с этими ключами, а с++ модуль прилинковать отдельно Вы так пробовали? Я что-то сильно сомневаюсь что так можно. Ключик-то называется ВСЯ программа -fwhole-program. При таком способе компиляции вроде как даже и объектные файлы-то не создаются.
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Mar 4 2011, 10:56
|

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

|
Цитата(demiurg_spb @ Mar 4 2011, 13:50)  Вы так пробовали? Я что-то сильно сомневаюсь что так можно. Ключик-то называется ВСЯ программа -fwhole-program. При таком способе компиляции вроде как даже и объектные файлы-то не создаются. Вот, баловался летом... Код # #$(NAME).elf : $(CSRC) # @echo $^ # @$(CC) -c $(CFLAGS) -combine -fwhole-program $^ $(LDFLAGS) -o $(NAME).o # $(CC) $(NAME).o $(LDFLAGS) -o $@ Создаётся один обобщённый объектник из пачки исходников, который потом линкуется на общих основаниях
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|