Как поручить avr-gcc оптимизировать изменчивые переменные? - PullRequest
0 голосов
/ 30 мая 2018

Код для обработчика службы прерываний:

volatile unsigned char x = 0;
void interruptHandler() __attribute__ ((signal));
void interruptHandler() {
    f();
    g();
}

Вызовы:

void f() { x ++; } // could be more complex, could also be in a different file
void g() { x ++; } // as `f()`, this is just a very simple example

Поскольку x - переменная переменная, она читается и записывается при каждом ее использовании.Тело обработчика прерываний компилируется в (avr-gcc -g -c -Wa,-alh -mmcu=atmega328p -Ofast file.c):

lds r24,x
subi r24,lo8(-(1))
sts x,r24
lds r24,x
subi r24,lo8(-(1))
sts x,r24

Теперь я могу вручную встроить функции и использовать временную переменную:

unsigned char y = x;
y ++;
y ++;
x = y;

Или я могу просто написать:

x += 2;

Оба примера компилируются с гораздо более эффективными:

lds r24,x
subi r24,lo8(-(2))
sts x,r24

Можно ли сказать avr-gcc, чтобы оптимизировать доступ к переменным переменным внутри interruptHandlerто есть, чтобы выполнить мою ручную оптимизацию автоматически?

В конце концов, пока работает interruptHandler, глобальные прерывания отключены, и x невозможно изменить.Я предпочитаю не выполнять оптимизацию кода вручную, возможно создавая дублирующийся код (если f() и g() необходимы в другом месте) и внося ошибки.

Ответы [ 2 ]

0 голосов
/ 26 июня 2018

Если вы объявите переменную как volatile, то все обращения к ней будут volatile - компилятор будет считывать и записывать ее ровно столько раз, сколько говорит исходный код, без их объединения или выполнения подобных оптимизаций.

Так что, если вы хотите объединить оптимизацию, объявите переменную без «volatile» - тогда вы получите то, что вам нужно внутри кода прерывания.

И затем извне кода прерывания вы можете принудительно осуществить волатильный доступ, используя что-токак этот макрос:

#define volatileAccess(v) *((volatile typeof((v)) *) &(v))

Используйте «volatileAccess (x)» вместо «x» вне кода прерывания.

Только не забывайте, что «volatile» не означает «атомарный»"!

0 голосов
/ 13 июня 2018

Можно ли сказать avr-gcc оптимизировать доступ к изменчивым переменным внутри interruptHandler, т.е. выполнить мою ручную оптимизацию автоматически?

Нет, это невозможно в Clanguage.

В конце концов, пока работает interruptHandler, глобальные прерывания отключены

Компилятор не знает это - и вы можете просто поставитьsei в обработчик, чтобы включить их снова.

Также обратите внимание, что аппаратные регистры тоже объявлены volatile.Некоторые из них - например, регистр данных UART - имеют побочные эффекты, даже когда read .Компилятор не должен удалять какие-либо операции чтения или записи для них.

...