|
|
 |
Ответов
|
Sep 29 2011, 15:13
|
Участник

Группа: Участник
Сообщений: 26
Регистрация: 21-09-11
Пользователь №: 67 308

|
да, прерывание использую. выход из ситуации нашел. в обработчике прерываний у меня объявлялся массив. этот массив сделал глобальным и стека стало хватать. по меню пройдусь) спасибо за помощь)
|
|
|
|
|
Oct 7 2011, 09:22
|

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

|
QUOTE (defunct @ Oct 2 2011, 01:15)  volatile можно ставить на семафор взводимый в прерывании, который говорит о том, что данные поменялись, но никак не на сами данные - иначе это равносильно тотальному отключению оптимизации. Спорно. Спорили тут полтора года назад: http://electronix.ru/forum/index.php?s=&am...st&p=747603. С наступлением эры LTO (link-time optimization) в gcc может стать чертовски актуально.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Oct 7 2011, 21:55
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(Сергей Борщ @ Oct 7 2011, 12:22)  Спорно. Спорили тут полтора года назад: http://electronix.ru/forum/index.php?s=&am...st&p=747603. С наступлением эры LTO (link-time optimization) в gcc может стать чертовски актуально. Если насчет "head" я могу согласиться, то насчет записи в буфер уж никак нет. У компилятора нет повода менять действия местами - так как разрешение прерываний есть volatile операция: # define sei() __asm__ __volatile__ ("sei" :: ) Можно ее считать программным data sync barrier'ом. Volatile на асм инструкцию однозначно указывает компилятору, что все действия описанные до этой инструкции должны быть завершены. Если была запись в буфер, то компилятор не имеет право отложить ее за пределы volatile инструкции. В то же время объявив данные буфера как volatile, Вы мешаете компилятору отложить запись до удобного момента. Что это за удобный момент, - например, до разрешения прерываний в буфер может быть положено что-то еще, и на ARM логично было бы сгруппировать все записи в одну burst инструкцию. Так вероятно и поступил бы компилятор, не объяви Вы каждое слово сторейджа как volatile. Ниже привожу функцию: Код foo(void) { int a = read_something_not_critical_and_slow(); U32 iMask = ILock(); // запрет прерываний int b = read_something_critical_fast();
.... } Я лично на 100% уверен, что действие "read_something_not_critical_and_slow" произойдет строго до запрета прерываний, а действие "read_something_critical_fast" произойдет строго после запрета прерываний. Если какой-то оптимизатор соптимизирует иначе, то он ничего не соображает в оптимизации. Так откуда же взялись сомнения насчет записи в буфер?  Цитата Ради экономии пары volatile и одной временной переменной? Вы сталкивались с системами где RAM access time >50 clk для одно-тактового CPU? (для систем с DRAM это типично) пара лишних volatile может стоит >50% ресурсов проца.
|
|
|
|
|
Oct 8 2011, 08:59
|

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

|
QUOTE (defunct @ Oct 8 2011, 00:55)  Volatile на асм инструкцию однозначно указывает компилятору, что все действия описанные до этой инструкции должны быть завершены. Если была запись в буфер, то компилятор не имеет право отложить ее за пределы volatile инструкции. Этот момент для меня не совсем ясен. Надо обдумать. В той ветке ReAl приводил пример, когда такая инструкция не мешала перенести запись в не-volatile переменную. И я не готов ответить, кто прав в этом случае - вы или компилятор. QUOTE (defunct @ Oct 8 2011, 00:55)  В то же время объявив данные буфера как volatile, Вы мешаете компилятору отложить запись до удобного момента. Что это за удобный момент, - например, до разрешения прерываний в буфер может быть положено что-то еще, и на ARM логично было бы сгруппировать все записи в одну burst инструкцию. Так вероятно и поступил бы компилятор, не объяви Вы каждое слово сторейджа как volatile. Боюсь, с учетом сказанного выше, на данный момент не существует способа объяснить компилятору допустимость этого. QUOTE (defunct @ Oct 8 2011, 00:55)  Я лично на 100% уверен, что действие "read_something_not_critical_and_slow" произойдет строго до запрета прерываний, а действие "read_something_critical_fast" произойдет строго после запрета прерываний. Если какой-то оптимизатор соптимизирует иначе, то он ничего не соображает в оптимизации. Я, напротив, на 100% уверен, что компилятор может сделать иначе и с оптимизацией у него все в порядке. Если тело этих read_... ему доступно и оно не имеет побочных эффектов - то имеет полное право. QUOTE (defunct @ Oct 8 2011, 00:55)  Вы сталкивались с системами где RAM access time >50 clk для одно-тактового CPU? (для систем с DRAM это типично) пара лишних volatile может стоит >50% ресурсов проца. Нет, не сталкивался. И точно также как и вы против использования лишних volatile. Мы лишь расходимся в критериях опредения, который именно считать лишним.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Oct 8 2011, 23:18
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(Сергей Борщ @ Oct 8 2011, 11:59)  Я, напротив, на 100% уверен, что компилятор может сделать иначе и с оптимизацией у него все в порядке. Если тело этих read_... ему доступно и оно не имеет побочных эффектов - то имеет полное право. Значит фтопку такой компилятор. Побочный эффект - прерывания будут запрещены дольше чем требуется либо не тогда когда нужно! Volatile инструкция как раз и указывает компилятору на то, что изменение порядка следования действий влечет к непредсказуемому результату. Допустим компилятор видит, что расчет переменной "a" состоит из расчета переменной "b" плюс какие-то длительные дополнительные действия. Пусть эффективность функции "foo" будет выше если вначале расчитать значение переменной "b", а затем значение переменной "a". Но увеличив эффективность функции можно убить эффективность/функциональность всей системы, если поменяется порядок следования volatile инструкции. (я не зря в примере нарисовал всего три действия, перестановка расчета любой из переменных - выглядит как перестановка запрета прерываний)! Если вдруг заметите, что gcc при каких-то опциях оптимизации меняет порядок следования volatile инструкции, - стоит репортить баг и пусть фиксят компилятор. И нам дайте знать в какой версии такое имеет место быть, чтобы ее не пользовать! ) Цитата(Сергей Борщ @ Oct 8 2011, 11:59)  Боюсь, с учетом сказанного выше, на данный момент не существует способа объяснить компилятору допустимость этого. Очень жаль, что они тогда оптимизируют в gcc непонятно. burst инструкция (STRM) при работе с DDR/SDRAM будет до 8 крат быстрее в сравнении с одиночными STR.
|
|
|
|
|
Oct 10 2011, 07:13
|

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

|
QUOTE (defunct @ Oct 9 2011, 02:18)  Если вдруг заметите, что gcc при каких-то опциях оптимизации меняет порядок следования volatile инструкции, - стоит репортить баг и пусть фиксят компилятор. volatile как раз говорит о побочном эффекте. Я же написал - если содержимое этих функций не имеет побочных эффектов. И если в этих функциях нет volatile и нет вызова внешних функций - компилятор имеет право. А volatile вы сами рекомендуете в них убрать.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Oct 10 2011, 21:39
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(Сергей Борщ @ Oct 10 2011, 10:13)  volatile как раз говорит о побочном эффекте. Я же написал - если содержимое этих функций не имеет побочных эффектов. И если в этих функциях нет volatile и нет вызова внешних функций - компилятор имеет право. А volatile вы сами рекомендуете в них убрать. Так-с Расставим точки над i. Вот ваша цитата: Цитата Кстати, и буфер тоже должен быть volatile. В противном случае компилятор имеет полное право перенести запись в буфер после изменения Head и разрешения прерывания. Я утверждаю - не должен он быть volatile, и рекомендую буфер и его элементы НЕ обьявлять как volatile. Пусть компилятор оптимизирует запись и обращения к буферу. Потому что разрешение прерывания - есть volatile инструкция, и компилятор ни при каких условиях (если в нем нет багов) не имеет права изменять ее порядок появления в коде. Он не может перенести запись после разрешения прерываний как вы говорите, т.к. поменяется порядок volatile инструкции "sei". Кстати команда "RETI" в GCC также объявлена как volatile, поэтому сделать запись в буфер после выхода из обработчика прерывания компилятор тоже не имеет права. Компилятор может лишь только вообще не писать в буфер, если обращений к нему больше нигде нет, но порядок следования команд, запись -> разрешение прерываний, на другой, он поменять не может!..
|
|
|
|
|
Oct 11 2011, 06:27
|

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

|
QUOTE (defunct @ Oct 11 2011, 00:39)  Потому что разрешение прерывания - есть volatile инструкция, и компилятор ни при каких условиях (если в нем нет багов) не имеет права изменять ее порядок появления в коде. Он не может перенести запись после разрешения прерываний как вы говорите, т.к. поменяется порядок volatile инструкции "sei". Вы не правы - он не может изменить ее порядок относительно других volatile-инструкций (или выражений с побочными эффектами). В противном случае он обязан был бы перед этой инструкцией выгрузить в ОЗУ содержимое всех регистров, в которых закешированы любые переменные. Но этого не происходит - достаточно посмотреть листинг. А вот если мы буфер сделаем volatile - он уже будет обязан сгрузить его в ОЗУ перед sei. QUOTE (defunct @ Oct 11 2011, 00:39)  Компилятор может лишь только вообще не писать в буфер, если обращений к нему больше нигде нет, но порядок следования команд, запись -> разрешение прерываний, на другой, он поменять не может!.. Мне кажется в этом вы ошибаетесь. Обратите внимание на пример ReAl в конце сообщения №36 той ветки.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
Сообщений в этой теме
_trunk_ Переполнен стек Sep 29 2011, 11:35 kovigor Цитата(_trunk_ @ Sep 29 2011, 14:35) Подс... Sep 29 2011, 13:33 _trunk_ рекурсии не использую. а как увеличить стек? Sep 29 2011, 14:26 kovigor Цитата(_trunk_ @ Sep 29 2011, 17:26) реку... Sep 29 2011, 14:43 777777 Цитата(_trunk_ @ Sep 29 2011, 19:13) да, ... Sep 30 2011, 12:10  paskal Цитата(777777 @ Sep 30 2011, 16:10) Интер... Sep 30 2011, 16:07   777777 Цитата(paskal @ Sep 30 2011, 20:07) Очеви... Oct 5 2011, 04:02  _Артём_ Цитата(xemul @ Sep 30 2011, 19:14) В масс... Sep 30 2011, 18:21          defunct Много всего написал, потом удалил, потому как не х... Oct 16 2011, 23:04           Сергей Борщ QUOTE (defunct @ Oct 17 2011, 02:04) Пере... Oct 17 2011, 06:07            defunct Цитата(Сергей Борщ @ Oct 17 2011, 09:07) ... Oct 17 2011, 12:03 Абырвалг Цитата(_trunk_ @ Sep 29 2011, 20:13) да, ... Oct 7 2011, 04:57
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|