GenaSPB 11 13 августа, 2012 Опубликовано 13 августа, 2012 · Жалоба Странно, мало. Мой проект выложен в теме, в нём нет ассемблера вообще. Может, у Вас что-то мешает оптимизатору? У меня только ключ -Os. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 13 августа, 2012 Опубликовано 13 августа, 2012 · Жалоба Линкеру нужны ещё такие ключи как оказалось... -nodefaultlibs -lm -lgcc -lc С ними правильные либы подключаются. Да и кстати с lto у меня небольшие проекты (до 16К) собираются нормально. Наконец-то lto полноценно заменил combine. А то блин я уже было отчаялся ждать этого радостного момента:) Вот пример похвальной оптимизации: //fifo.tx.cnt - волатильная переменная uint16_t; //было: if (!(--rs->fifo.tx.cnt)) 624c: 80 91 15 06 lds r24, 0x0615 6250: 90 91 16 06 lds r25, 0x0616 6254: 01 97 sbiw r24, 0x01 ; 1 6256: 90 93 16 06 sts 0x0616, r25 625a: 80 93 15 06 sts 0x0615, r24 625e: 80 91 15 06 lds r24, 0x0615 6262: 90 91 16 06 lds r25, 0x0616 6266: 89 2b or r24, r25 6268: 29 f4 brne .+10 ; 0x6274 //стало: if (!(--rs->fifo.tx.cnt)) 613c: 80 91 15 06 lds r24, 0x0615 6140: 90 91 16 06 lds r25, 0x0616 6144: 01 97 sbiw r24, 0x01 ; 1 6146: 90 93 16 06 sts 0x0616, r25 614a: 80 93 15 06 sts 0x0615, r24 614e: 89 2b or r24, r25 6150: 29 f4 brne .+10 ; 0x615c Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 13 августа, 2012 Опубликовано 13 августа, 2012 (изменено) · Жалоба Ну -nodefaultlibs немного не в тему... А в результате (-flto -Os) теперь вместо 27 килобайт 26 стало... И это всё от изначального объёма 32 килобайта... Я тоже давно ждал этого! (-flto -Os добавил в ключи линкера). Изменено 13 августа, 2012 пользователем Genadi Zawidowski Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
halfdoom 0 13 августа, 2012 Опубликовано 13 августа, 2012 · Жалоба Может, у Вас что-то мешает оптимизатору? У меня только ключ -Os. Тоже Os, просто код написан в стиле "здесь оптимизатору делать нечего". Компилятору остается только грамотно разложить переменные по регистрам. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 13 августа, 2012 Опубликовано 13 августа, 2012 · Жалоба Я как раз писал в стиле "оптимизируйте пожалуйста", но это оптимизировалось уже несколько последних лет одинаково. Например, я проверял - нет смысла внутри выражения делать присваивания, что снижает читаемость - оптимизатор gcc это давным-давно реорганизовывал. Но -flto порадовало! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 13 августа, 2012 Опубликовано 13 августа, 2012 · Жалоба Вот пример похвальной оптимизации Что-то такая трактовка volatile начинает напрягать. Они, получается, неявно сделали винегрет из атомарной операции преддекремента и принципиальных неатомарностей доступа к переменной. Получается, что преддекремент живет своей жизнью... правда, хорошо бы примерчик придумать, где это вредно, но фантазии пока не хватает. Наверное, пока ни у кого не хватило. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 14 августа, 2012 Опубликовано 14 августа, 2012 · Жалоба Ну -nodefaultlibs немного не в тему...Кому как... У меня без этого на одном из проектов было +2К в сравнении с WinAVR, и это с lto. Что-то такая трактовка volatile начинает напрягать.Ну не знаю... Я специально старался писать код так чтобы получить именно то, что наконец получилось. Ничего вредного пока в этом не усматриваю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 14 августа, 2012 Опубликовано 14 августа, 2012 · Жалоба Ну не знаю... Я специально старался писать код так чтобы получить именно то, что наконец получилось. Ничего вредного пока в этом не усматриваю. Вы имеете в виду одним выражением? Дык тут - никаких возражений, вопросы именно по поводу того что CSE(вспомнил, как оно называется), имеет более высокий приоритет, чем безусловная по определению отмена оптимизации у volatile. Оно-то симпатичнее выглядит, но, с виду, конфликтует со стандартами. Полезши в гугль, нашел, откуда ножки. Вкратце - поскольку имеется сильная заточенность под х86, инкремент волатайла при работе CSE, происходит через косвенное обращение к памяти, и за одну команду, что load/store архитектурах невозможно. Где-то там и вычитал такой пример. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 15 августа, 2012 Опубликовано 15 августа, 2012 · Жалоба Вы имеете в виду одним выражением?Да. Дык тут - никаких возражений, вопросы именно по поводу того что CSE(вспомнил, как оно называется), имеет более высокий приоритет, чем безусловная по определению отмена оптимизации у volatile. Оно-то симпатичнее выглядит, но, с виду, конфликтует со стандартами.Да и шут с ним с конфликтом, главное чтобы программы работали так как от них ожидаешь. Или даже немного лучше:-) Возвращаясь к avr-gcc-4.7.1... Обнаружился один неприятный и один непонятный момент. 1) Все переменные в EEPROM секции располагаются в обратном порядке, т.е. было раньше x1 x2 x3, стало x3 x2 x1. Такая фигня была уже как-то раз на одной из версий WinAVR её быстро тогда пофиксили. 2) При включении lto все неиспользуемые переменные из EEPROM выкидываются нафиг. Мне пока видится только один выход: засунуть все EEPROM переменные в одну структуру. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 14 15 августа, 2012 Опубликовано 15 августа, 2012 · Жалоба Мне пока видится только один выход: засунуть все EEPROM переменные в одну структуру. Есть ещё __attribute__((used)) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 15 августа, 2012 Опубликовано 15 августа, 2012 · Жалоба Мне пока видится только один выход: засунуть все EEPROM переменные в одну структуру. А совместно с offsetof это решение позволит ещё и независящие от типа используемой памяти писать программы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 15 августа, 2012 Опубликовано 15 августа, 2012 · Жалоба Мне пока видится только один выход: засунуть все EEPROM переменные в одну структуру. Я никогда по другому и не делал :) В любой момент может возникнуть желание сделать резервный набор параметров. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 14 15 августа, 2012 Опубликовано 15 августа, 2012 · Жалоба А совместно с offsetof это решение позволит ещё и независящие от типа используемой памяти писать программы. Это как? Методы чтения-то всё равно зависят от типа используемой памяти. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 15 августа, 2012 Опубликовано 15 августа, 2012 · Жалоба Это как? Методы чтения-то всё равно зависят от типа используемой памяти. Именно. А пользоваться тем, что эта память ещё одно адресное пространство на атмеге - всё равно, надо перед обращениями дожидаться заверщения циклов записи, ранее (возможно) иницииорваных... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ReAl 0 16 августа, 2012 Опубликовано 16 августа, 2012 · Жалоба Что-то такая трактовка volatile начинает напрягать. ... правда, хорошо бы примерчик придумать, где это вредно, но фантазии пока не хватает. С примерчиком нет проблем, хоть и, возможно, слегка натянутым. Нужно просто придумывать на периферии, а не в ОЗУ. Пусть у нас есть регистр периферийного устройства (нет проблем описать его так, что компилятор как таковой не сможет его отличить от переменной в памяти). Пусть младший бит всегда читается нулевым а запись единички в него запускает какую-то операцию. Специально так аппаратуру сделали под INC для запуска операции, остальные управляющие биты при этом не меняются (во времена PDP-11 такое встречалось). Все нули в регистре тоже что-то означают (скажем, отсутствие ошибок). Ну вот читаем оттуда все нули, инкрементиреуем, записываем назад с 1 в младшем бите. Вместо того, чтобы опять зачитать регистр и увидеть, что там все нули -- всегда в этой опреации видим регистр ненулевым. А по поводу напряга… Ой, вредные они все. Я бы тоже считал, что после записи в volatile его нужно перезачитать. Но… Там, кажется, и в С++ что-то слегка менялось. Боюсь, что это где-то вблизи того, что --i эквивалентно «присваивающему выражению» i = i - 1. А оно имеет «значение правой части приведенное к типу левой части со снятыми cv-квалификаторами» Близкая проблема volatile int va; int a; a = va = 5; // надо ли перезачитывать va??? говорят, что таки не надо... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться