|
|
  |
Доступ к переменной или регистру – что быстрее?, ATMega8 |
|
|
|
Sep 24 2014, 07:16
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Камень ATMega8 среда IAR Тот кто пишет на ассемблере конечно знает такие тонкости. Что быстрее Код if(mot_state == UP) // do something Или Код if(PORTC_Bit1) // do something Или так Код #define CHECKBIT(ADDRESS,BIT) (ADDRESS & (1<<BIT)) If(CHECKBIT(PORTC,PORTC1)) // do something
Сообщение отредактировал Jenya7 - Sep 24 2014, 07:21
|
|
|
|
|
Sep 24 2014, 08:20
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(Сергей Борщ @ Sep 24 2014, 13:35)  В общем случае зависит от настроек компилятора. Что мешает вам скомпилить и посмотреть листинг? Листинг получился малоинформативный, для меня по крайней мере Код // 399 if(PINC_Bit1) ??main_0: IN R16, 0x06 // 400 { // 401 //do something // 402 } // 403 // 404 if(mot_state == UP) LDS R16, (ir_code + 4) // 405 { // 406 //do something // 407 } Но чисто визуально работа с переменной требует больше телодвижений.
Сообщение отредактировал Jenya7 - Sep 24 2014, 08:24
|
|
|
|
|
Sep 24 2014, 09:24
|

Частый гость
 
Группа: Участник
Сообщений: 156
Регистрация: 27-09-06
Из: Irkutsk
Пользователь №: 20 747

|
Цитата а что разместит- гарантии нет Нет, хотя бы потому, что может элементарно не хватить регистров. Размещаются эти регистры в АЛУ, т.е.в General Purpose Working Registers. А порты это периферия, к ядру они никак не относятся.
--------------------
Блог о разработке на CC430, SIM900, GPS, ARM и не только...
|
|
|
|
|
Sep 24 2014, 09:33
|

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

|
Цитата(Mihey_K @ Sep 24 2014, 12:43)  Доступ в регистр всегда быстрее. Для принудительного размещения переменной в регистре используйте ключевое слово register. Регистр регистру рознь. Если РОН (из регистрового файла ядра) - то да. А если периферийный - то ничем не отличается от памяти, только шина другая. Хотя, видел давненько уже фишку, когда переменную размещали в неиспользуемых регистрах. Может, и есть разница, за счет более короткой адресации
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Sep 24 2014, 11:28
|

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

|
Цитата(Jenya7 @ Sep 24 2014, 11:20)  Листинг получился малоинформативный, для меня по крайней мере Ваш компилятор достаточно умен - видя, что внутри if() ничего нет, он выкинул и сам if(). А вот чтение регистра PORTC выкинуть не имел права, поэтому все свелось к одной команде IN. Попробуйте так: Код if(mot_state == UP) // do something asm(" nop ");
if(PORTC_Bit1) // do something asm(" nop "); Цитата(Mihey_K @ Sep 24 2014, 11:43)  Доступ в регистр всегда быстрее. Для принудительного размещения переменной в регистре используйте ключевое слово register. Если бы вы прочитали не только заголовок, но и сам вопрос, вы бы поняли, что автор спрашивал не о регистре общего назначения, а о регистре ввода-вывода. Причем для регистров ядра таких команд нет. Цитата(MrYuran @ Sep 24 2014, 12:33)  А если периферийный - то ничем не отличается от памяти, только шина другая. Для первых 32 периферийных регистров регистров у AVR есть короткие команды доступа (IN, OUT) и команды проверки отдельных битов. Цитата(Jenya7 @ Sep 24 2014, 13:00)  Проблема что ног не хватает Покажите схему, если это не государственная тайна. Возможно мы сможем найти другие места, где сэкономить ноги.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Sep 24 2014, 11:55
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(Сергей Борщ @ Sep 24 2014, 17:28)  Покажите схему, если это не государственная тайна. Возможно мы сможем найти другие места, где сэкономить ноги. Схема вот Цитата(Сергей Борщ @ Sep 24 2014, 17:28)  Ваш компилятор достаточно умен - видя, что внутри if() ничего нет, он выкинул и сам if(). А вот чтение регистра PORTC выкинуть не имел права, поэтому все свелось к одной команде IN. Попробуйте так: Код if(mot_state == UP) // do something asm(" nop ");
if(PORTC_Bit1) // do something asm(" nop "); Таки да Код // 399 if(PINC_Bit1) ??main_0: SBIC 0x06, 0x01 // 400 { // 401 asm(" nop "); nop // 402 } // 403 // 404 if(mot_state == UP) ??main_1: LDS R16, (ir_code + 4) CPI R16, 1 BRNE ??main_2 // 405 { // 406 asm(" nop "); nop // 407 }
|
|
|
|
|
Sep 25 2014, 08:23
|

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

|
Цитата(Jenya7 @ Sep 24 2014, 14:55)  Схема вот Судя по названию цепей OC0A и OC0B - процессор у вас не ATmega8, а ATmega88. У него есть прерывания PCINT по изменению уровня на любой ноге. Соответственно не нужен сигнал PCINT20 и R28, VD1-VD3. Вот и освобождается нога. Можно кнопки But подключить к резистивному делителю и опрашивать одной ногой при помощи АЦП - это еще две ноги. P.S. А если SW1 подключить не к питанию, а к земле - можно сэкономить R1-R4 за счет внутренних подтяжек.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Sep 25 2014, 10:32
|

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

|
Цитата(Сергей Борщ @ Sep 25 2014, 12:23)  Судя по названию цепей OC0A и OC0B - процессор у вас не ATmega8, а ATmega88. Если это не ATmega8, а ATmega88, то вообще лафа! Т.е. у последней есть свободные регистры GPIOR0, GPIOR1, GPIOR2, специально зарезервированные для таких целей. Эти регистры хороши тем, что имеют малые адреса, позволяющие обращаться к ним через инструкции IN и OUT, а потому очень удобны для хранения каких либо битовых флагов, используемых в процедурах прерывания (чтобы у тех и код был короче, и скорость выполнения быстрее). Их даже вируальными не надо объявлять, поскольку они по своей природе уже такие. В серии XMega таких регистров целый непрерывный блок - 16 штук (байт), а потому там на них можно и длинные переменные заводить. Однако толку от этого практически нет, поскольку адреса у тех регистров длинные (двухбайтные), а потому обращение к ним такое же, как к памяти.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|