|
avr-libc и uint64_t арифметика, или баг, или я чего-то не понимаю... |
|
|
|
Sep 28 2009, 16:46
|

Профессионал
    
Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581

|
Код volatile uint64_t v1; volatile uint32_t v2;
int main(void) { v2 = v1/v2; PORTD = 12; while(1); } этот тривиальный код компилируется для attiny2313 в 3940 байтов flash и 278 байт ОЗУ!!!! это как такое называется?! при этом если обе переменные v1 и v2 сделать uint32_t, то размер кода становится практически в 20 раз меньше: 200 байт flash !!! что там такое в libc понаделано, что получается такое разрастание кода?! ведь если руками написать функцию деления "в столбик" - получится код значительно меньше... P.S. разумеется, оптимизация -Os
--------------------
Я бы взял частями... но мне надо сразу.
|
|
|
|
|
Sep 28 2009, 18:13
|
Участник

Группа: Участник
Сообщений: 21
Регистрация: 25-04-07
Пользователь №: 27 294

|
Ну дык никто не мешает посмотреть получившийся код... Первое, что бросается в глаза - при 64 бит активно используется стек, в то время как при 32 бит обходится только регистрами. Плюс появляется множество ненужных пересылок. Вообще создалось впечатление, что тут "не ступала нога оптимизатора", несмотря на -Os.
|
|
|
|
|
Sep 28 2009, 19:08
|

Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 6-08-07
Из: Приднестровье, Тирасполь
Пользователь №: 29 581

|
Цитата(Lepeksiy @ Sep 28 2009, 21:13)  .... создалось впечатление, что тут "не ступала нога оптимизатора", несмотря на -Os. А чего ей там ступать, если все переменные volatile...
--------------------
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
|
|
|
|
|
Sep 28 2009, 19:27
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(Goodefine @ Sep 29 2009, 01:08)  А чего ей там ступать, если все переменные volatile... По аналогии все волатильные лонги тогда нужно перечитывать побайтно. Ведь в операции "v2 = v1/v2" и v1 и v2 считываются только 1 раз, а уж где их потом разместит компилятор - его личное дело, хоть в регистрах, хоть в стеке, но это месторасположение уже не будет волатильным. ИМХО - это недоработка оптимизации. Однозначно надо исправлять. Цитата(ARV @ Sep 28 2009, 22:46)  этот тривиальный код компилируется для attiny2313 в 3940 байтов flash и 278 байт ОЗУ!!!! А в attiny2313 стока есть?
Сообщение отредактировал GetSmart - Sep 28 2009, 19:25
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Sep 28 2009, 20:52
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Там таки явно что-то не то. Зачем-то большая таблица в ОЗУ Код 00800060 <__clz_tab>: 800060: 00 01 movw r0, r0 800062: 02 02 muls r16, r18 800064: 03 03 mulsu r16, r19 800066: 03 03 mulsu r16, r19 800068: 04 04 cpc r0, r4 80006a: 04 04 cpc r0, r4 80006c: 04 04 cpc r0, r4 80006e: 04 04 cpc r0, r4 800070: 05 05 cpc r16, r5 800072: 05 05 cpc r16, r5 800074: 05 05 cpc r16, r5 800076: 05 05 cpc r16, r5 800078: 05 05 cpc r16, r5 80007a: 05 05 cpc r16, r5 80007c: 05 05 cpc r16, r5 80007e: 05 05 cpc r16, r5 800080: 06 06 cpc r0, r22 ... 80014c: 08 08 sbc r0, r8 80014e: 08 08 sbc r0, r8 800150: 08 08 sbc r0, r8 800152: 08 08 sbc r0, r8 800154: 08 08 sbc r0, r8 800156: 08 08 sbc r0, r8 800158: 08 08 sbc r0, r8 80015a: 08 08 sbc r0, r8 80015c: 08 08 sbc r0, r8 80015e: 08 08 sbc r0, r8 и сам код деления какой-то странный, толи на С писанный, толи совсем непонятно что. Надо исходники качнуть, глянуть. upd: Фигушки, это не avr-libc надо смотреть, а libgcc upd: оййо.... В общем исходнике на libgcc2.c , которій в зависимости от #defin-ов по разному работает и пітается типа оптимизировать скорость проверяя на 0-не0 старшие части и подвызывая другие функции (в комментариях что-то про встроенній асм, но я их вообще не нашёл). Таблица в .data от того же исходника, она не используется, но и не выбрасывается даже по -Wl,-gc-sections, так как библиотека собрана без -fdata-sections
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Sep 28 2009, 21:59
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(GetSmart @ Sep 28 2009, 22:27)  ИМХО - это недоработка оптимизации. Однозначно надо исправлять. Не оптимизации, а библиотеки поддержки. Её нужно "персонализировать" как-то. Может проще будет так, как с другими вещами сделано, многое в libm затолкано, которая из avr-libc - если её подключить, то размер кода уменьшается, так как берутся оптимизированные версии оттуда.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Sep 28 2009, 22:53
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(ReAl @ Sep 29 2009, 00:52)  upd: оййо.... В общем исходнике на libgcc2.c , которій в зависимости от #defin-ов по разному работает и пітается типа оптимизировать скорость проверяя на 0-не0 старшие части и подвызывая другие функции (в комментариях что-то про встроенній асм, но я их вообще не нашёл). Там все сводится к функции __udivmodsi4 (деление 32бит/32бит) которая для AVR в файле gcc/config/avr/libgcc.S , и __udivmodsi4 написана вполне прилично, а вот то что в libgcc2.c это конечно кошмар кошмар
|
|
|
|
|
Sep 29 2009, 04:31
|

Профессионал
    
Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581

|
Цитата(IgorKossak @ Sep 28 2009, 23:13)  ARV, Вы полагаете, что разработчики где-то здесь, чтобы Вам ответить? Или это просто так, чтобы повозмущаться? слабость знания английского не позволяет мне запостить вопрос в ином месте... здесь время от времени появляется Aesok, которого я причислил к лику разработчиков  во всяком случае он не раз давал советы/ответы из самых глубин GCC - на него надеюсь и уповаю  кстати, -lm не помогает уменьшить размер кода. Цитата(GetSmart) А в attiny2313 стока есть? в тини стока нет, но компилятору-то по барабану  да и не в тини дело - для меги такой код тоже великоват как-то...
--------------------
Я бы взял частями... но мне надо сразу.
|
|
|
|
|
Oct 1 2009, 18:00
|

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

|
скомпилял этот пример вот что получилось для -Os -mmcu=atmega64 Цитата .file "int64.c" __SREG__ = 0x3f __SP_H__ = 0x3e __SP_L__ = 0x3d __tmp_reg__ = 0 __zero_reg__ = 1 .global __do_copy_data .global __do_clear_bss .text .global main .type main, @function main: push r2 push r3 push r4 push r5 push r6 push r7 push r8 push r9 push r10 push r11 push r12 push r13 push r14 push r15 push r16 push r17 /* prologue: function */ /* frame size = 0 */ lds r18,v1 lds r19,v1+1 lds r20,v1+2 lds r21,v1+3 lds r22,v1+4 lds r23,v1+5 lds r24,v1+6 lds r25,v1+7 lds r2,v2 lds r3,(v2)+1 lds r4,(v2)+2 lds r5,(v2)+3 movw r10,r2 movw r12,r4 clr r14 clr r15 ldi r16,lo8(0) ldi r17,lo8(0) call __udivdi3 movw r24,r18 movw r26,r20 sts v2,r24 sts (v2)+1,r25 sts (v2)+2,r26 sts (v2)+3,r27 ldi r24,lo8(12) out 50-0x20,r24 .L2: rjmp .L2 .size main, .-main .comm v1,8,1 .comm v2,4,1 для -Os -mmcu=attiny2313 Цитата .file "int64.c" __SREG__ = 0x3f __SP_H__ = 0x3e __SP_L__ = 0x3d __tmp_reg__ = 0 __zero_reg__ = 1 .global __do_copy_data .global __do_clear_bss .text .global main .type main, @function main: push r2 push r3 push r4 push r5 push r6 push r7 push r8 push r9 push r10 push r11 push r12 push r13 push r14 push r15 push r16 push r17 /* prologue: function */ /* frame size = 0 */ lds r18,v1 lds r19,v1+1 lds r20,v1+2 lds r21,v1+3 lds r22,v1+4 lds r23,v1+5 lds r24,v1+6 lds r25,v1+7 lds r2,v2 lds r3,(v2)+1 lds r4,(v2)+2 lds r5,(v2)+3 movw r10,r2 movw r12,r4 clr r14 clr r15 ldi r16,lo8(0) ldi r17,lo8(0) rcall __udivdi3 movw r24,r18 movw r26,r20 sts v2,r24 sts (v2)+1,r25 sts (v2)+2,r26 sts (v2)+3,r27 ldi r24,lo8(12) out 50-0x20,r24 .L2: rjmp .L2 .size main, .-main .comm v1,8,1 .comm v2,4,1 я не заметил криминала по размеру, на счет правильности нада конечно проверить но.. я изредко интами 64 пользуюсь - вроде работало. теперь нада лесть в __udivdi3 avr-libc как я понимаю вообще нипричем. операции над стандартными целыми типами - исключительно компиллер в libgcc реализует тут какято поППа - 3312 инструкций... нада поглядеть исходнички! посмотрел... в исходничке libgcc2.c есть реализация на асме операции деления 32/32 , как мне кажется можно по образу и подобию изготовить 64/64 если найдется доброволец взятся за эту учебную задачку высеч сей гранитный монумент я поробую всунуть его под основание фундамента avr GCC, Анатолий Соколов польет это сверху цементом используя комит в транк эсвэна.
|
|
|
|
|
Oct 2 2009, 13:42
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(klen @ Oct 1 2009, 21:00)  если найдется доброволец взятся за эту учебную задачку высеч сей гранитный монумент я поробую всунуть его под основание фундамента avr GCC, Анатолий Соколов польет это сверху цементом используя комит в транк эсвэна. Гляну в выходные, ничего особого в задаче нет. Можно даже сразу два варианта - глянуть на тему деления без восстановления остатка - немного больше по коду, но быстрее. И подкинуть монетку - что вписывать (на ребро - под условную компиляцию). Кстати, и это может больше к Анатолию вопрос - если в структуре gcc есть места для делений 64/32, 32/16 и т.п. и их ещё нет, то можно одним махом дописать.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Oct 2 2009, 21:46
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(Petka @ Oct 2 2009, 23:01)  т.е. такой большой код не потому, что так написали для AVR в GCC, а потому что соответствующий код для GCC не написан, и была взята реализация написанная на Си? да, именно так для AVR GCC Асм процедур для 64бит нет и поэтому работает обобщенный С код Цитата(ReAl @ Oct 2 2009, 17:42)  Кстати, и это может больше к Анатолию вопрос - если в структуре gcc есть места для делений 64/32, 32/16 и т.п. и их ещё нет, то можно одним махом дописать. ИМХО, в GCC увы нет возможности задействовать 64/32, 32/16 и т.п., там только 64/64, 32/32, ... но если я ошибаюсь то например 32/16 у меня где-то есть, ну и 64/32 тоже не вопрос.
|
|
|
|
|
Oct 2 2009, 22:15
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(singlskv @ Oct 3 2009, 00:46)  ИМХО, в GCC увы нет возможности задействовать 64/32, 32/16 и т.п., там только 64/64, 32/32, ... Ну нет так нет. "леди, покидающая автомобиль, увеличивает его скорость". В смысле "баба з возу". Хотя делать там особо нечего.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Oct 4 2009, 19:19
|
Группа: Участник
Сообщений: 7
Регистрация: 2-10-09
Пользователь №: 52 714

|
Интересно, зачем вам на авээрах делить 64-битные числа?
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|