Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Доступ к переменной или регистру – что быстрее?
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
Jenya7
Камень 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, 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     }


Но чисто визуально работа с переменной требует больше телодвижений.
Mihey_K
Доступ в регистр всегда быстрее. Для принудительного размещения переменной в регистре используйте ключевое слово register.
megajohn
Цитата(Mihey_K @ Sep 24 2014, 12:43) *
Доступ в регистр всегда быстрее. Для принудительного размещения переменной в регистре используйте ключевое слово register.

как раз недавно читал книжку, и это директива, как бы намек компилятору, что переменная будет часто использоваться, и не соизволите ли вы её разместить в регистре =)
а что разместит - гарантии нет
Jenya7
Цитата(Mihey_K @ Sep 24 2014, 14:43) *
Доступ в регистр всегда быстрее. Для принудительного размещения переменной в регистре используйте ключевое слово register.

а в каком регистре переменная будет сохранена (если будет по megajohn sm.gif) ? в General Purpose I/O Registers или General Purpose Working Registers?
Mihey_K
Цитата
а что разместит- гарантии нет

Нет, хотя бы потому, что может элементарно не хватить регистров.
Размещаются эти регистры в АЛУ, т.е.в General Purpose Working Registers. А порты это периферия, к ядру они никак не относятся.
MrYuran
Цитата(Mihey_K @ Sep 24 2014, 12:43) *
Доступ в регистр всегда быстрее. Для принудительного размещения переменной в регистре используйте ключевое слово register.

Регистр регистру рознь.

Если РОН (из регистрового файла ядра) - то да.
А если периферийный - то ничем не отличается от памяти, только шина другая.

Хотя, видел давненько уже фишку, когда переменную размещали в неиспользуемых регистрах.
Может, и есть разница, за счет более короткой адресации
Jenya7
Вопрос возник потому как я опрашиваю AB Encoder, одна ножка А другая B – так мы знаем направление движения мотора. Проблема что ног не хватает, так я думал опрашивать только А а направление считывать из переменной.
MrYuran
Цитата(Jenya7 @ Sep 24 2014, 14:00) *
Проблема что ног не хватает, так я думал опрашивать только А а направление считывать из переменной.

А в переменной оно откуда возьмется?
Jenya7
Цитата(MrYuran @ Sep 24 2014, 16:08) *
А в переменной оно откуда возьмется?

нажал на одну кнопку - направление UP , на другую - DOWN.
Сергей Борщ
Цитата(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) *
Проблема что ног не хватает
Покажите схему, если это не государственная тайна. Возможно мы сможем найти другие места, где сэкономить ноги.
Jenya7
Цитата(Сергей Борщ @ 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     }
Сергей Борщ
Цитата(Jenya7 @ Sep 24 2014, 14:55) *
Схема вот
Судя по названию цепей OC0A и OC0B - процессор у вас не ATmega8, а ATmega88. У него есть прерывания PCINT по изменению уровня на любой ноге. Соответственно не нужен сигнал PCINT20 и R28, VD1-VD3. Вот и освобождается нога. Можно кнопки But подключить к резистивному делителю и опрашивать одной ногой при помощи АЦП - это еще две ноги.

P.S. А если SW1 подключить не к питанию, а к земле - можно сэкономить R1-R4 за счет внутренних подтяжек.
Xenia
Цитата(Сергей Борщ @ Sep 25 2014, 12:23) *
Судя по названию цепей OC0A и OC0B - процессор у вас не ATmega8, а ATmega88.


Если это не ATmega8, а ATmega88, то вообще лафа! Т.е. у последней есть свободные регистры GPIOR0, GPIOR1, GPIOR2, специально зарезервированные для таких целей.

Эти регистры хороши тем, что имеют малые адреса, позволяющие обращаться к ним через инструкции IN и OUT, а потому очень удобны для хранения каких либо битовых флагов, используемых в процедурах прерывания (чтобы у тех и код был короче, и скорость выполнения быстрее). Их даже вируальными не надо объявлять, поскольку они по своей природе уже такие.

В серии XMega таких регистров целый непрерывный блок - 16 штук (байт), а потому там на них можно и длинные переменные заводить. Однако толку от этого практически нет, поскольку адреса у тех регистров длинные (двухбайтные), а потому обращение к ним такое же, как к памяти.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.