Страница 1 из 2

register var - для быстрого доступа к глобальной переменной

Добавлено: Чт апр 16, 2020 15:29:07
sunjob
добрый день

на сколько правомочный код (для быстрого доступа к глобальной переменной) ... по аналогии с лок. переменными?
(предполагаю, что где-та тут лажа... но без хорошего знания ассемблера, пока сложно расковырять зерно :о)

Код: Выделить всё

uint16_t register adc1,adc2;

int main(void) 
{
extern uint16_t adc1, adc2;
...
}
avr-gcc / atmega328

спасибо

Re: register var - для быстрого доступа к глобальной перемен

Добавлено: Чт апр 16, 2020 16:02:45
ARV
локальные переменный чаще всего и так будут регистровыми. а в том виде, как вы описали, в AVR-GCC (к примеру) вообще не скомпилируется - нужно явно указывать регистр(ы) хранения, да еще и явно запрещать компилятору использовать этот регистр под другие цели.
имхо, геморрою вы поиметь сможете, а выигрыш будет сомнительным...

Re: register var - для быстрого доступа к глобальной перемен

Добавлено: Чт апр 16, 2020 17:46:05
sunjob
> локальные переменный чаще всего и так будут регистровыми
ну дык! :о)

> вообще не скомпилируется
да ну?!

> нужно явно указывать регистр(ы) хранения, да еще и явно запрещать компилятору использовать этот регистр под другие цели.
поподробнее?

> геморрою вы поиметь сможете
не без этого, не обляпаешься, не попробувавшись ...

> а выигрыш будет сомнительным...
потестим, посмотрим, для этого и шкрябаем царапками...

п.с. выхлоп сборки, надеюсь, не нужен? (мини-шаблон собирается в avr-gcc без ошибок)

п.с.2 спасиб... :о) понятно, что я и сам буду рыть в этом направлении, но комменты и уточнения не помешают

Re: register var - для быстрого доступа к глобальной перемен

Добавлено: Чт апр 16, 2020 18:34:28
ARV
Что вы хотите выиграть? Имхо, овчинка выделки не стоит.

Re: register var - для быстрого доступа к глобальной перемен

Добавлено: Чт апр 16, 2020 18:49:15
sunjob
> для быстрого доступа к глобальной переменной

может и не стоит, но потестировать ни кто не мешает! (или есть более весомые аргументы?)

что мы теряем? если глобальная переменная будет регистровая, то при постоянном обращении к ней - получаем плюс в виде скорости обращения.
какие минусы?

ваши мысли?

Re: register var - для быстрого доступа к глобальной перемен

Добавлено: Чт апр 16, 2020 18:53:38
ARV
В каком-то синтетическом тесте вы, возможно, результата и добьетесь, но в практической задаче вряд ли.
Я при помощи регистровых переменных утрамбовывал в attiny13 код, который иначе не влезал, но речь шла не о скорости... И все ломалось при малейших правках, так что в итоге я отказался от части функций, вместо постоянной борьбы с компилятором.

Re: register var - для быстрого доступа к глобальной перемен

Добавлено: Чт апр 16, 2020 19:12:00
sunjob
хорошо, а чуть более подробно, если не сложно?

+

т.е. нет смысла оптимизировать глобальную переменную?

Re: register var - для быстрого доступа к глобальной перемен

Добавлено: Пт апр 17, 2020 04:12:21
oleg110592
может пригодиться - есть апноут Atmel "AVR4027: Tips and Tricks to Optimize Your C Code for 8-bit AVR Microcontrollers", тут перевод:
http://microsin.net/programming/avr-tro ... t-avr.html
4.5 Постоянная привязка переменной к регистру

Это можно сделать с помощью определения переменной с директивой register:

register unsigned char counter asm("r3");
Обычно так можно безопасно использовать регистры r2 .. r7. Регистры r8 .. r15 могут использоваться для передачи аргументов компилятором, когда в функции передается много аргументов. Если не этот случай, то эти регистры также можно использовать для привязки к переменным.

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

Для дополнительной информации см. врезку "Имена языка C, используемые в коде ассемблера"...

Re: register var - для быстрого доступа к глобальной перемен

Добавлено: Пт апр 17, 2020 04:34:06
OKF
sunjob, вы хотите сэкономить на спичках, а результата преобразования АЦП, небось, будете ждать хрен знамо сколько.)

Re: register var - для быстрого доступа к глобальной перемен

Добавлено: Пт апр 17, 2020 05:03:12
ARV
sunjob писал(а):хорошо, а чуть более подробно, если не сложно?
во-первых, oleg110592, как обычно, не учитывает, что все развивается, и советы 10-летней давности сегодня могут оказаться бесполезными. современные версии avr-gcc имеют такие механизмы оптимизации, что советы, данные в рекомендованной статье, далеко не в каждом случае оказывают эффект. более того, в упомянутой статье не рассмотрены многие ключи оптимизации, дающие заметный эффект на "маленьких" микроконтроллерах. об использовании регистровых переменных в той статье сказано далеко не все важное, в связи с чем сегодня пользоваться рекомендациями скорее нежелательно, чем полезно.

во-вторых, использование регистровых переменных делает одновременно две вещи:
1. упрощает доступ к хранимым в них данных
2. затрудняет работу компилятора
поскольку компилятор использует распределение регистров по определенным встроенным правилам, то, принудительно исключая из списка доступных ему регистров некоторые под регистровую переменную, вы можете сломать встроенные оптимизации, и, вместо положительного, получить отрицательный элемент. например, вы затребовали регистр r6 (я беру наугад, на самом деле существуют довольно жесткие ограничения по использованию регистров для таких целей - вот тут ссылку в статье, рекомендованной oleg110592, все-таки следует изучить), а компилятор хочет (по своей встроенной логике) использовать этот регистр для каких-то вычислений. в этом случае компилятор запросто может сначала запихать r6 в стек, затем занести в него новое значение, провести вычисления, а затем извлечь из стека. ну и где тут выигрыш в скорости?! а ведь если вы не предпримите специальных действий (см. далее), компилятор вообще может наплевать на то, что в r6 ваши данные, и затереть их своими! и вы поимеете такой гемор при отладке, что я за вас не порадуюсь.

в третьих, вы обязаны блокировать использование регистров, выделенных вами под регистровые переменные, при помощи флага -ffixed-xx (для предыдущего примера это -ffixed-r6), чтобы компилятор всегда помнил, что этот регистр нельзя использовать в своих целях.
sunjob писал(а):т.е. нет смысла оптимизировать глобальную переменную?
не всегда, но чаще всего нет.
мне приходилось это делать в нескольких проектах с одной целью: мне нужно было обеспечить наибыстрейшую обработку переменной в прерывании. пришлось заводить регистровую переменную, чтобы при входе в обработчик не нужно было сохранять/восстанавливать регистры для работы с нею. ну и в аналогичных случаях еще в паре проектов пришлось так же поступать. и мой опыт позволяет мне утверждать, что если с одной однобайтной переменной еще можно чего-то добиваться разумными усилиями, то две и более однобайтных регистровых глобальных переменных, или, тем более, две или более двухбайтных регистровых переменных - это уже нескончаемый геморрой с непредсказуемыми последствиями.

уже лет 5 не делаю даже попыток подобного рода, полагаясь на оптимизации компилятора.

Re: register var - для быстрого доступа к глобальной перемен

Добавлено: Пт апр 17, 2020 06:23:59
Reflector
[uquote="ARV",url="/forum/viewtopic.php?p=3828704#p3828704"]а ведь если вы не предпримите специальных действий (см. далее), компилятор вообще может наплевать на то, что в r6 ваши данные, и затереть их своими! и вы поимеете такой гемор при отладке, что я за вас не порадуюсь.

в третьих, вы обязаны блокировать использование регистров, выделенных вами под регистровые переменные, при помощи флага -ffixed-xx (для предыдущего примера это -ffixed-r6), чтобы компилятор всегда помнил, что этот регистр нельзя использовать в своих целях.[/uquote]
Это где такое написано? Неужели здесь:

If you want to recompile source files that do not actually use your global register variable
so they do not use the specified register for any other purpose, you need not actually add
the global register declaration to their source code. It suffices to specify the compiler option
‘-ffixed-reg’ to reserve the register.

Re: register var - для быстрого доступа к глобальной перемен

Добавлено: Пт апр 17, 2020 06:45:21
oleg110592
[uquote="ARV",url="/forum/viewtopic.php?p=3828704#p3828704"]во-первых, oleg110592, как обычно, не учитывает, что все развивается, и советы 10-летней давности сегодня могут оказаться бесполезными.[/uquote]
учитывает как обычно, но как обычно ARV не внимательно читает посты, поскольку
1) о версии компилятора, который у ТС не было ни слова, а для загрузок по прежнему доступен например даже WinAVR2002, наверное не зря
https://sourceforge.net/projects/winavr/files/WinAVR/
2) написано - "может пригодиться", значит может и не пригодиться

Re: register var - для быстрого доступа к глобальной перемен

Добавлено: Пт апр 17, 2020 07:00:09
technik-1017
Использование регистров как глобальных переменных полезная вещь. Я думаю, что их начинают использовать при оптимизации написанного кода, устраняя узкие места.
Как уже писалось, обычно это прерывания. Также можно использовать для хранения различных флагов.
Работал в основном с IAR, никаких побочных эффектов не замечал. Если не ошибаюсь, то можно было использовать даже несколько регистров для одной переменной.
Была только одна особенность: объявленная таким образом переменная не инициализировалась по умолчанию в отличии от обычных переменных. В переменной был мусор и инициализировать приходилось принудительно.

Re: register var - для быстрого доступа к глобальной перемен

Добавлено: Пт апр 17, 2020 07:28:39
ARV
Reflector писал(а):Неужели здесь
именно. если в проекте несколько модулей, при компиляции каждого надо не использовать указанный регистр, чтобы не поиметь проблем.
oleg110592 писал(а):о версии компилятора, который у ТС не было ни слова
как и в вашем совете о версии компилятора, для которого данные советы пригодны, не было ни слова.

Re: register var - для быстрого доступа к глобальной перемен

Добавлено: Пт апр 17, 2020 07:39:49
oleg110592
опять не внимательность, по ссылке на перевод AVR4027 написано
2.3 Платформа разработки

Примеры кода и результаты тестирования этого документа базируются на следующих условиях:

1. Интегрированная система разработки (Integrated Development Environment, IDE): Atmel AVR Studio® 5 (Version: 5.0.1119).
2. AVR GCC 8-bit Toolchain Version: AVR_8_bit_GNU_Toolchain_3.2.1_292 (gcc version 4.5.1).
3. Целевой микроконтроллер AVR (Target Device): Atmel ATmega88PA.
Самый свежий тулчаин на сайте Атмел вроде недалеко ушел, судя по версии GCC - может все будет работать

Re: register var - для быстрого доступа к глобальной перемен

Добавлено: Пт апр 17, 2020 08:10:28
sunjob
может пригодиться - есть апноут Atmel "AVR4027
именно ее и читал (втч)
советы 10-летней давности сегодня могут оказаться бесполезными
жесткие ограничения по использованию регистров
о версии компилятора
и да и конечно... почитал, ознакомился в меру "ознакомляемости и впихуемости ознакомлений", все это как-бы да, ознакомлено/проразмыслено/проглочено... но я особо никогда не заглублялся в ASM-код, кишки, поэтому !!! решил поспрашить боевых котов, поподробнее, че, где у кого можно украсть повкуснее всяки-шняшки, на какие тапки/неожиданности/пакости можно напроться итп!

спасибо!

п.с. но вы не останавливайтеся, продолжайте, всяко нам-котам пригодиться!

п.с.2 еще раз спасибо!

Код: Выделить всё

- avr-gcc-4.9.2 / default
- avr-binutils-2.25
- avr-gcc-4.9.2
- avr-gdb-7.8.1
- avr-libc-1.8.1
- avra-1.4.1
- avrdude_5.11.1
- avrdude_6.3
- simavr-1.5
- simulavr-2017.05.21
- avr-add toolchain (3.4.2, 3.4.3, 3.5.4, 3.6.1.1752, 3.6.2.1759, gcc-9.2.0)

slackware 12.2/x32

Re: register var - для быстрого доступа к глобальной перемен

Добавлено: Пт апр 17, 2020 08:14:12
Reflector
[uquote="ARV",url="/forum/viewtopic.php?p=3828768#p3828768"]именно. если в проекте несколько модулей, при компиляции каждого надо не использовать указанный регистр, чтобы не поиметь проблем.[/uquote]
Это понятно, но блокировать использование указанного регистра при помощи флага -fixxed-reg никто не обязан, объявления регистровой переменной достаточно, но все модули должны его видеть.

Re: register var - для быстрого доступа к глобальной перемен

Добавлено: Пт апр 17, 2020 08:53:39
sunjob
> никто не обязан
имеется в виду что? никто не обязан за нас? или что?
- блокировать не обязательно (достаточно объявить регистровую переменную)?
- блокировать обязательно (не смотря на регистровое объявление)?

я думаю, судя по "начиткам", что
- при возможности компилятор будет использовать "переменную в регистре"
- по невозможности - не будет (видимо, должен быть соотв. варнинг)
- получается что -fixxed-reg - не обязательный ключ и/или должен использоваться для принудительного использования "регистра"

на счет последнего - только догадки, надо уточнить :о)

Re: register var - для быстрого доступа к глобальной перемен

Добавлено: Пт апр 17, 2020 09:31:52
ARV
sunjob писал(а):имеется в виду что? никто не обязан за нас? или что?
имеется ввиду, что есть формальные правила, а есть практические правила.

я вам дал совет из разряда практических правил - делайте, как я рекомендовал, и проблем не будет вообще никогда. но формалисты считают, что это не корректный совет, т.к. формально, если вы объявите регистровую переменную в заголовочном файле и этот файл приинклюдите в каждом файле своего проекта, использовать ключ -ffixed-reg будет не обязательно. так вот, поскольку даже в этом случае этот ключик можно использовать (не обязательно - не строгое требование, можно игнорировать), окажется, что мой совет работает всегда, а вот этот "формально правильный" - только при соблюдении неких условий.

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

какое правило требует большего напряжения ума для того, чтобы ему следовать? ;)
sunjob писал(а):на счет последнего - только догадки, надо уточнить
когда объявляете где-либо регистровую переменную, используйте этот ключ всегда, и никогда не поимеете проблем (с этим регистром). уточнять не надо, гарантируется разработчиками компилятора.

Re: register var - для быстрого доступа к глобальной перемен

Добавлено: Пт апр 17, 2020 10:37:21
Demiurg
Хотите быстро - используйте ассемблерные вставки. Компилятор все равно будет действовать по своему хотению. Если программа небольшая, напишите всю программу на асме.