реклама на сайте
подробности

 
 
> IAR EWAVR - как избавиться от лишних команд?
kv_addr
сообщение Aug 27 2011, 14:37
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 208
Регистрация: 6-07-04
Из: Полтава
Пользователь №: 279



В критичных по времени функциях использую зарезервированные РОН из нижней половины, в нижеуказанном примере r14 и r15:
CODE
...
volatile __regvar __no_init char Old_PINB @14;
volatile __regvar __no_init char New_PINB @15;
...
Old_PINB = New_PINB;
New_PINB = PINB;
...


Получаю в результате:
CODE
// 70 Old_PINB = New_PINB;
MOV R14, R15
// 71 New_PINB = PINB;
IN R16, 0x03
MOV R15, R16

В вышеуказанном примере последовательность команд IN R16,0x03 и MOV R15,R16 явно лишняя, достаточно было одной команды IN R15,0x03. Расходуется лишняя пара байтов и лишний такт. Казалось бы мелочь, но такого при работе с зарезервированными под переменные регистрами может набежать вполне прилично.

Да, конечно, можно написать критичные по времени модули на ассемблере, но все же, если бы можно было избежать подобных несуразностей при компиляции сишного кода, было бы всяко лучше.

Мог бы кто нибудь подсказать, как в EWAVR это можно побороть, или сия бага есть врожденная фича EWAVR?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Xenia
сообщение Aug 27 2011, 17:12
Сообщение #2


Гуру
******

Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237



Цитата(kv_addr @ Aug 27 2011, 20:15) *
В пункте Register Utilization я могу зарезервировать от одного (R15) до 12 (R4...R15) операционных регистров под глобальные переменные. Поскольку работать с переменными, расположенными в регистрах, можно быстрее, чем с переменными расположенными в ячейках ОЗУ, в критичных по времени функциях пытаюсь использовать такую возможность, что в моем случае вполне оправдано. Но компилятор генерирует не совсем оптимальный код, пример которого привел выше.

Резервирование это одно, а компиляция через инструкцию IN - другое. Резервирование означает только то, что компилятору запрещается использовать эти регистры при генерации C-кода (причем за библиотеки компилятор отвественности не несет, т.к. получает их уже скомпилированными). Нечего кроме этого операция резервирование не означает. Т.е. только от этого память не станет регистром, а регистр не станет памятью.

С точки зрения компилятора регистр отличается от памяти способом адресации. Хотя с точки зрения электронщика это может быть одно и тоже sm.gif. В отношении регистра компилятор использует команды IN и OUT, тогда как к памяти обращается по ее адресу. В этом и состоит это отличие.

Регистры объявлены в хидере с помощью определения SFR_B или ему подобных, описанных в iomacro.h. Эти определения сильно компиляторозависимые, а потому не стоит повторять те приемы, которыми они там определятся как регистры, хотя самим SFR_B пользоваться вполне можно. Например так:
SFR_B(Old_PINB, 14)
SFR_B(New_PINB, 15)
Но лучше, все-таки так не делать, а найти в хидере уже определенные имена регистров из области 14-го и 15-го байта. Там должно быть что-то вроде этого:
SFR_B(?????, 0xE)
SFR_B(?????, 0xF)
Вот с этими именами, которые у меня записаны, как "?????", и нужно определить тождество через #define и тогда такие клоны тоже будут использоваться компилятором, как регистры.

Попытки же использовать зарезервированное среди регистров место по адресу (@14 или @15) приводит лишь к тому, что это место используется, как память. Т.е. обращение к нему будет происходить по адресам 14 или 15, а не регистровыми опрациями IN/OUT.

Цитата(kv_addr @ Aug 27 2011, 20:15) *
Объясните, пожалуйста, если я хочу старое и новое значения байтов, полученных из порта PINB, хранить именно в РОН и дальше в функции работать именно с данными в этих регистрах (естественно, учитывая ограничения для нижних 16 РОН у AVR), то чем Ваши вышеуказанные дефайны могут мне помочь?

Дефайны помогают тем, что отожествляют ваши имена Old_PINB и New_PINB с именами регистров, а не с памятью. А это позволяет обращаться к ним, как к регистрам, используя команды IN/OUT. А ваше определение этих имен, как переменных, с указанными для них адресами (@14 или @15), является определением для ячеек памяти. По этой причине компилятор в их отношении команды IN/OUT не использует.

Я понимаю, что вы хотели бы, чтобы компилятор сам догадался, что по адресам 14 и 15 находятся регистры. Однако догадаться об этом он не может. Причина в том, что эти адреса считаются от начала сегмента кода! А где начинается сегмент кода знает только линкер, а компилятор этого не знает и знать не должен. Поэтому в данном случае вина лежит целиком на вашем корявом программировании, а не на компиляторе замечательной фирмы IAR. sm.gif

Цитата(kv_addr @ Aug 27 2011, 20:15) *
У меня Old_PINB и New_PINB являются однобайтовыми глобальными переменными, расположенными в регистрах R14 и R15 соответственно, а отнюдь не регистры портов PORTE и PORTF.

А в моем AT90USB647 по адресам 14 и 15 находятся именно регистры PORTE и PORTF! Вы ведь поленились назвать тип вашего МК? А раз так, то не имеете права выставлять мне претензий за то, что я ваши 14-ю и 15-ю ячейки неправильно отнесла. Телепатическими способностями в отношении вас я не обладаю, поэтому в своем прошлом ответе ограничилась вежливой формулировкой "имена регистров ищите в хидере, соответствующему вашему типу МК". Почему бы вам и в самом деле не посмотреть, как называются у вашего МК регистры, находящиеся в 14-ом и 15-ом байтах?
Go to the top of the page
 
+Quote Post
kv_addr
сообщение Aug 27 2011, 18:56
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 208
Регистрация: 6-07-04
Из: Полтава
Пользователь №: 279



"Девушка, пожалуйста, не кричите очень громко, я Вас и так неплохо слышу"©1111493779.gif sm.gif

Цитата
А в моем AT90USB647 по адресам 14 и 15 находятся именно регистры PORTE и PORTF! Вы ведь поленились назвать тип вашего МК?


Если Вас интересует контроллер, то в данном конкретном случае это ATmega88, хотя может быть и любой иной из атмеловских 8-биток, в том числе и Ваш AT90USB647. У них у всех имеются одни и те же 32 восьмибитных регистра общего назначения (РОН), по-импортному они еще называются General Purpose Working Registers. Ну, те самые, которые от R0 до R31 принято именовать.
Вы, очень похоже, спутали их с регистрами ввода/вывода (РВВ), по-импортному I/O Registers, кои в общем адресном пространстве находятся над РОН. Видимо, ввиду атмеловских безобразий с нумерацией регистров и возникло это недоразумение. Тот же Ваш горячо любимый PORTE гады атмелцы нумеруют как 0x0E (0x2E), а PINF (не PORTF, тут Вы ошиблись) как 0x0E (0x2E).

Дык, вот, как Вы могли уже заметить, я не собирался и не собираюсь использовать ни PORTE, ни даже PINF для хранения регистровых глобальных переменных, у меня запросы несколько скромнее:

Прикрепленное изображение


А именно, как бы какое-то количество из нижних 12 РОН задействовать под быстродоступные переменные. Что в самом принципе компилятором допускается и я с удовольствием этой возможностью пользуюсь. Но вот только смущает несколько не совсем логичное поведение компилятора, плодящего избыточный код в казалось бы очевидной, однозначно интерпретируемой ситуации.

Что же касательно Вашего предположения относительно того, что компилятор считает зарезервированный под переменную РОН как ячейку памяти, в которую напрямую без дополнительного РОН из старших 16, которые обычно используются компилятором в качестве локальных (в примере это R16), невозможно положить содержимое того же регистра ввода/вывода PINB, то может такое и можно было бы заподозрить, если бы для передачи байта из одного зарезервированного РОН в другой точно так же задействовался бы дополнительный РОН-костыль.

Скажем, такое для переброса байта из одной ячейки в другую вполне нормально, команды ячейка/ячейка у этих контроллеров нет.

Но ведь на самом деле в скомпилированном коде нет последовательности MOV R16,R15 MOV R14,R16 или нет даже попытки задействовать команды LD и ST, а байт передается одной вполне логичной командой MOV R14,R15. Т.е. здесь компилятор не пытается почесать левое ухо правой ногой.

Так почему он боится напрямую передать байт из РВВ в РОН вполне логичной штатной командой, а пристегивает сюда еще один, явно не нужный РОН R16? Можно ли избежать этой несуразности компилятора?

Надеюсь, я вполне внятно сформулировал вопрос?
Go to the top of the page
 
+Quote Post
Xenia
сообщение Aug 27 2011, 19:00
Сообщение #4


Гуру
******

Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237



Цитата(kv_addr @ Aug 27 2011, 22:56) *
Так почему он боится напрямую передать байт из РВВ в РОН вполне логичной штатной командой, а пристегивает сюда еще один, явно не нужный РОН R16? Можно ли избежать этой несуразности компилятора?

Поставьте режим оптимизации, хотя бы в минимальной степени, и этот эффект исчезнет.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Aug 27 2011, 19:19
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(Xenia @ Aug 27 2011, 23:00) *
... эффект исчезнет.
Нет, не исчезнет... В данном случае: либо смириться с таким поведением компилятора, либо (раз уж начали использовать нестандартные средства) пойти дальше - использовать ассемблерные вставки.
Go to the top of the page
 
+Quote Post
kv_addr
сообщение Aug 27 2011, 19:31
Сообщение #6


Местный
***

Группа: Свой
Сообщений: 208
Регистрация: 6-07-04
Из: Полтава
Пользователь №: 279



Цитата(Палыч @ Aug 27 2011, 23:19) *
Нет, не исчезнет... В данном случае: либо смириться с таким поведением компилятора, либо (раз уж начали использовать нестандартные средства) пойти дальше - использовать ассемблерные вставки.

Собственно говоря, я хотел выяснить, является ли возможным образумить компилятор. И если да, то каким образом.
Если же нет, это тоже не так уж страшно, рисуем ассемблерные модули. Для себя делаем заметку - имеется бага компилера и это есть его встроенная фича.

Правда, интересно было бы узнать, может кто-то смог побороть эту "фичу"?
Go to the top of the page
 
+Quote Post
zhevak
сообщение Aug 28 2011, 08:08
Сообщение #7


Знающий
****

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



Цитата(kv_addr @ Aug 28 2011, 01:31) *
Собственно говоря, я хотел выяснить, является ли возможным образумить компилятор. И если да, то каким образом.
Если же нет, это тоже не так уж страшно, рисуем ассемблерные модули. Для себя делаем заметку - имеется бага компилера и это есть его встроенная фича.

Правда, интересно было бы узнать, может кто-то смог побороть эту "фичу"?

Ситуацию понял. Но по сути вопроса мне сказать ничего, поэтому прошу прощения за оффтоп.

Перфекционизм -- это плохо. Иногда нужно просто решать задачу. Любым способом.
Решить ее и двигаться дальше. Но когда насущная задача в подсознании подменяется задачей "красиво" решить, то имеется нехилая вероятность зависнуть на ней и потерять кучу времени. А потом, наверстывая упущенное, наговнокодить. Единственный совет наверно может быть такой -- не бойтесь написать говнокод. Вы ведь знаете, что это есть говонокод -- а это главное. Конечно, по возможности нужно избегать такой практики, но жизнь есть жизнь и не всегда получается срать красиво. (Простите и меня за мой хранцузский). Не надо бояться говокода там, где он не влияет на конечный результат. Что касается меня, то я обычно в таких случая ставлю в своих исходниках предупреждающие значки типа

CODE
// TODO: Причеши бабушкин код

или
CODE
// TODO: Не забудь убрать за собой свои засранки

или
CODE
// TODO: Проблема решена с помощью тупого быдлокода.


Потом, когда появляется свободное время можно будет и поупражняться в перфекционизме.

Программисты -- они всё еще в душе художники. Но программирование -- уже давно не искусство, а ремесло.
Соблюдайте баланс между искусством и ремеслом в своей работе и не позволяйте ситуации управлять вами!



--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
Go to the top of the page
 
+Quote Post
kv_addr
сообщение Aug 28 2011, 13:05
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 208
Регистрация: 6-07-04
Из: Полтава
Пользователь №: 279



Цитата(zhevak @ Aug 28 2011, 12:08) *
Ситуацию понял. Но по сути вопроса мне сказать ничего, поэтому прошу прощения за оффтоп.
Перфекционизм -- это плохо. Иногда нужно просто решать задачу. Любым способом.
...
Потом, когда появляется свободное время можно будет и поупражняться в перфекционизме.
Программисты -- они всё еще в душе художники. Но программирование -- уже давно не искусство, а ремесло.
Соблюдайте баланс между искусством и ремеслом в своей работе и не позволяйте ситуации управлять вами!

sm.gif
Хмм... Отвечу предельно просто. Решаю проблему всеми возможными средствами. Предпочитаю решать по возможности изысканно. Если так не получается, решаю менее "красивым" способом, лишь бы конечный результат был ВЕРНЫМ.
Если по ходу дела встретился вопрос, решение которого сулит на даный момент и впредь более "красивый" вариант решения, не премину попытаться с ним разобраться, если он решаем, этим решением буду пользоваться в дальнейшем. Но без особого фанатизма. Если получаю отрицательный ответ, ставлю заметку на сей счет и еду дальше, решая проблему иным образом. Вроде так.

Кстати, подбив все за и против, критичные по времени прерывания рисую на ассемблере. Мне это как бы и не очень страшно. sm.gif

PS: А вообще-то я в большей мере электронщик, чем программист, просто иногда приходится кой-чего выполнять на контроллерах, ну и соответственно писать для них программы, т.е. программирование есть дополнение к основной профессии.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- kv_addr   IAR EWAVR - как избавиться от лишних команд?   Aug 27 2011, 14:37
- - Xenia   Когда переменная объявлена с адресом памяти (напри...   Aug 27 2011, 15:25
|- - kv_addr   Цитата(Xenia @ Aug 27 2011, 19:25) Когда ...   Aug 27 2011, 16:15
|- - Палыч   Цитата(Xenia @ Aug 27 2011, 21:12) от это...   Aug 27 2011, 18:33
|- - kv_addr   Цитата(Xenia @ Aug 27 2011, 23:00) Постав...   Aug 27 2011, 19:15
- - Xenia   kv_addr, можно попросить вас выложить проектик для...   Aug 28 2011, 14:14
|- - kv_addr   Цитата(Xenia @ Aug 28 2011, 18:14) kv_add...   Aug 28 2011, 16:28
|- - Xenia   Цитата(kv_addr @ Aug 28 2011, 20:28) Нет ...   Aug 28 2011, 19:17
|- - kv_addr   Цитата(Xenia @ Aug 28 2011, 23:17) Мне на...   Aug 28 2011, 20:53
|- - Палыч   Цитата(Xenia @ Aug 28 2011, 23:17) с ваши...   Aug 31 2011, 05:37
|- - kv_addr   Цитата(Xenia @ Aug 28 2011, 23:17) Мне на...   Sep 2 2011, 13:41
|- - Xenia   Цитата(kv_addr @ Sep 2 2011, 17:41) И как...   Sep 2 2011, 15:04
|- - kv_addr   Цитата(Xenia @ Sep 2 2011, 19:04) Никак. ...   Sep 2 2011, 20:04
- - _Bill   Цитата(kv_addr @ Aug 27 2011, 18:37) В кр...   Aug 28 2011, 17:51
- - kv_addr   Цитата(_Bill @ Aug 28 2011, 21:51) Скорее...   Aug 28 2011, 18:34
- - _Bill   Цитата(kv_addr @ Aug 28 2011, 22:34) . Эт...   Aug 28 2011, 19:35


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 27th July 2025 - 01:02
Рейтинг@Mail.ru


Страница сгенерированна за 0.01471 секунд с 7
ELECTRONIX ©2004-2016