#1 2025-08-20 17:00:37

MikeM
Учасник
З Київ
Зареєстрований: 2017-11-03
Повідомлень: 173

Регістрова змінна

Коли компілятор зберігає змінну в регістрі, фрагмент програми працює в рази швидше. Але він може використовувати або не використовувати регістр за власним розсудом. Чи відомі комусь ВЛАСНОРУЧ ПЕРЕВІРЕНІ засоби змусити компілятор використовувати для змінної регістр. Ключове слово "register" не працює, принаймні у мене.

Неактивний

#2 2025-08-20 17:06:47

jokeer
Гість

Re: Регістрова змінна

Я так підозрюю, що змінна повинна влазити в регістр.

#3 2025-08-20 17:08:23

MikeM
Учасник
З Київ
Зареєстрований: 2017-11-03
Повідомлень: 173

Re: Регістрова змінна

Змінна байтова

Неактивний

#4 2025-08-20 17:38:56

jokeer
Гість

Re: Регістрова змінна

Це компіляторо-залежна магія.

The register keyword is not a guarantee that the variable will be placed in a register.

#5 2025-08-20 17:52:50

MikeM
Учасник
З Київ
Зареєстрований: 2017-11-03
Повідомлень: 173

Re: Регістрова змінна

But what the hell is a guarantee?

Неактивний

#6 2025-08-20 18:06:12

jokeer
Гість

Re: Регістрова змінна

Якщо компілятор вирішить що використати регістр буде прикольно - розмістить у регістрі. Можна спробувати вимкнути оптимізацію.
Якщо треба рахувати такти - краще на асемблері.

#7 2025-08-20 18:11:44

MikeM
Учасник
З Київ
Зареєстрований: 2017-11-03
Повідомлень: 173

Re: Регістрова змінна

Вимкнути оптимізацію - цікава ідея. Куди треба лізти для цього,

Неактивний

#8 2025-08-20 18:48:09

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 613

Re: Регістрова змінна

MikeM пише:

Чи відомі комусь ВЛАСНОРУЧ ПЕРЕВІРЕНІ засоби змусити компілятор використовувати для змінної регістр.

Стандартних таких засобів у мовах C та C++ немає.
Навіщо це вам потрібно? У більшості випадків (але не завжди) компілятор знає краще за програміста, де розміщувати змінну. Краще напишіть, яку саме проблему намагаєтесь вирішити використанням регістру для змінної.
Якщо таки потрібно, є власноруч перевірений GCC Inline Assembly.

MikeM пише:

Ключове слово "register" не працює, принаймні у мене.

register - це лише підказка компілятору, причому давно застаріла (deprecated).

MikeM пише:

Вимкнути оптимізацію - цікава ідея. Куди треба лізти для цього

Не треба. Примусове вимкнення оптимізації в сучасних компіляторах не має практичного сенсу. До того ж, це скоріш змусить НЕ використовувати регістр, ніж навпаки.

Неактивний

#9 2025-08-20 20:45:33

Honey
Учасник
З Київ
Зареєстрований: 2020-09-26
Повідомлень: 451

Re: Регістрова змінна

В avr-gcc можна об'явити глобальну змінну:
register uint8_t myregvar asm("r16");
вона гарантовано буде в r16, але код на C не буде з нею працювати оптимально.
На asm (або вставками на asm) з нею можна працювати як завгодно оптимально і одночасно мати доступ з C, це зручно, коли частина проекту на asm, а частина на C.

upd:
якщо потрібна двобайтова змінна, то:
register uint16_t myregvar asm("r16");
в коді на asm r16 буде молодшим, r17 - старшим

Остання редакція Honey (2025-08-20 20:56:53)

Неактивний

#10 2025-08-20 21:44:18

Kino
Учасник
Зареєстрований: 2019-02-28
Повідомлень: 57

Re: Регістрова змінна

Лет десять назад обратил внимание, что CodeVisionAVR по умолчанию начинает размещение переменных в регистрах (R0-R16), потом уже в памяти. В моем любимом IARе тоже надо явно указывать в программе как описал Honey для avr-gcc.

Неактивний

#11 2025-08-20 22:09:35

MikeM
Учасник
З Київ
Зареєстрований: 2017-11-03
Повідомлень: 173

Re: Регістрова змінна

dimich пише:

Навіщо це вам потрібно?

Формую відеосигнал зсувом байтової змінної. Якщо змінна в регістрі, то через однобітовий порт виводжу послідовно 8 бітів за 0,5 мікросекунди (сам у шоці). Якщо змінна не в регістрі - 1 біт за той же час. Різниця катастрофічна

Остання редакція MikeM (2025-08-20 22:20:31)

Неактивний

#12 2025-08-20 22:20:59

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 613

Re: Регістрова змінна

Honey пише:

В avr-gcc можна об'явити глобальну змінну:
register uint8_t myregvar asm("r16");

Це не специфічно для avr-gcc, для інших платформ теж так можна.

Honey пише:

вона гарантовано буде в r16, але код на C не буде з нею працювати оптимально.

Якщо точніше, гарантованим буде сайд-ефект у вигляді доступу до регістру при доступі до змінної. Саме значення може зберігатись в іншому регістрі, даючи деоптимізацію:

register uint8_t x asm("r16");

void foo(void)
{
    for (x = 0; x < 100; x++)
        GPIOR0 = x;
}
foo:
.L__stack_usage = 0
        ldi r24,0
.L2:
        mov r16,r24
        cpi r24,lo8(100)
        brlo .L3
        ret
.L3:
        out 0x1e,r24
        subi r24,lo8(-(1))
        rjmp .L2

https://godbolt.org/z/n4Kx4frGe

А якщо раптом помилково використати call-clobbered register і не побачити попередження від компілятора, то ловити баг можна буде дуже довго  smile

Неактивний

#13 2025-08-20 22:25:35

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 613

Re: Регістрова змінна

MikeM пише:

Формую відеосигнал зсувом байтової змінної. Якщо змінна в регістрі, то через однобітовий порт виводжу послідовно 8 бітів за 0,5 мікросекунди (сам у шоці). Якщо змінна не в регістрі - 1 біт за той же час. Різниця катастрофічна

Для такої задачі inline assembler - саме воно. Не обовʼязково inline, можна і в окремому source файлі.

Неактивний

#14 2025-08-20 22:33:03

jokeer
Гість

Re: Регістрова змінна

Формую відеосигнал зсувом байтової змінної.

Весь фреймбуфер все одно в 1 байт не влізе.Так то через SPI теж можна 1 байт дуже швидко вигрузити.

#15 2025-08-20 22:46:45

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 613

Re: Регістрова змінна

jokeer пише:

Так то через SPI теж можна 1 байт дуже швидко вигрузити.

Більше того, поки один вигружається, можна вже підготувати наступний. Але з атмеговим SPI-контролером "розриви" все одно будуть, бо регістр даних не буферизований. А якщо використати USART в режимі SPI, то можна практично без розривів.

Остання редакція dimich (2025-08-20 22:47:01)

Неактивний

#16 2025-08-20 22:55:08

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 613

Re: Регістрова змінна

A, якщо вдається 8 біт за 0.5 мкс, то там явно не атмега. Або розігнана до 32 МГц smile

Неактивний

#17 2025-08-20 23:09:26

akapulko
Гість

Re: Регістрова змінна

А чому б не використати якийсь штатний регістр, що не використовується за призначенням (напр.  OCRxA/B якогось таймера)?

#18 2025-08-20 23:25:59

MikeM
Учасник
З Київ
Зареєстрований: 2017-11-03
Повідомлень: 173

Re: Регістрова змінна

dimich пише:

A, якщо вдається 8 біт за 0.5 мкс, то там явно не атмега. Або розігнана до 32 МГц smile

Звичайнісінький 16 МГц UNO. Я ж казав "Сам у шоці"

Остання редакція MikeM (2025-08-20 23:29:56)

Неактивний

#19 2025-08-20 23:36:13

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 613

Re: Регістрова змінна

akapulko пише:

А чому б не використати якийсь штатний регістр, що не використовується за призначенням (напр.  OCRxA/B якогось таймера)?

Для чого, для оптимізації? Не плутайте регістри процесора з регістрами ввода-вивода. AVR не вміє бітові зсуви чи іншу арифметику над регістрами ввода-вивода, тільки set/clear bit.
А для "загального використання" є три I/O регістра GPIOR0-GPIOR2. Їх зручно використовувати для бітових флагів, що виставляються в обробниках переривань.

Неактивний

#20 2025-08-20 23:38:45

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 613

Re: Регістрова змінна

MikeM пише:

Звичайнісінький 16 МГц UNO. Я ж казав "Сам у шоці"

Тобто 1 біт за 1 такт на atmega328p? Щось тут не те.
(Я маю на увазі довільні дані, а не фіксований патерн)

Остання редакція dimich (2025-08-20 23:46:16)

Неактивний

#21 2025-08-21 00:19:14

MikeM
Учасник
З Київ
Зареєстрований: 2017-11-03
Повідомлень: 173

Re: Регістрова змінна

dimich пише:

Тобто 1 біт за 1 такт на atmega328p?

Саме так. Я не розумію, як таке може бути, але засоби об'єктивного контролю підтверджують signal.jpg

Остання редакція MikeM (2025-08-21 00:43:20)

Неактивний

#22 2025-08-21 00:29:13

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 613

Re: Регістрова змінна

MikeM пише:

Саме так. Я не розумію, як таке може бути, але засоби об'єктивного контролю підтверджують.

А можете показати код (тільки той, що виводить байт) та опції компіляції? Або дизасембльований код. Бо чудес не буває.

Неактивний

#23 2025-08-21 00:31:16

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 613

Re: Регістрова змінна

MikeM пише:

не знаю, як вставити фото екрана осциллографа

Внизу під вікном редагування "Завантаження". Там "Upload a file". Потім відкриваєте завантажений файл, копіюєте його адресу і вставляєте в текст.

Неактивний

#24 2025-08-21 00:36:06

MikeM
Учасник
З Київ
Зареєстрований: 2017-11-03
Повідомлень: 173

Re: Регістрова змінна

  shifter = figures[codePagePtr];
  PORTB = shifter;
  shifter = shifter >> 1;
  PORTB = shifter;
  shifter = shifter >> 1;
  PORTB = shifter;
  shifter = shifter >> 1;
  PORTB = shifter;
  shifter = shifter >> 1;
  PORTB = shifter;
  shifter = shifter >> 1;
  PORTB = shifter;
  shifter = shifter >> 1;
  PORTB = shifter;
  shifter = shifter >> 1;
  PORTB = shifter;

Неактивний

#25 2025-08-21 00:39:22

MikeM
Учасник
З Київ
Зареєстрований: 2017-11-03
Повідомлень: 173

Re: Регістрова змінна

shifter і є тією змінною, розміщення якої радикально впливає на швидкість
Розібрався з фото. Там виводиться байт 0b01010101 молодшим бітом вперед

Остання редакція MikeM (2025-08-21 00:45:12)

Неактивний

Швидке повідомлення

Введіть повідомлення і натисніть Надіслати

Підвал форуму