Отображение входных данных в массив (лучший способ?) - PullRequest
0 голосов
/ 06 февраля 2019

Я работаю во встроенной системе и "сопоставил" некоторые определения с массивом для входных данных.

volatile int INPUT_ARRAY[40];


#define INPUT01 INPUT_ARRAY[0]
#define INPUT02 INPUT_ARRAY[1]


// section 2
if ( INPUT01 && INPUT02 ) {
  writepin(outputpin, value);
}

Если я хочу читать из входа 1, я могу просто сказать newvariable = INPUT01 илиЯ могу сравнить данные с вводом 1, как в разделе 2 моего кода.Я не уверен, что это нормальный способ сопоставления имени INPUT01 с положением массива.Или для входного контакта в первую очередь.Каждое значение массива представляет двоичный вывод и считывается в массив путем декодирования значения порта (16 бит).Вопрос: Является ли использование определений и массивов, как этот, достаточно эффективным?

1 Ответ

0 голосов
/ 06 февраля 2019

Да, ваше решение эффективно.

Прежде чем компилятор C даже увидит ваш код, препроцессор C заменяет INPUT_ARRAY[0] на INPUT01 и, аналогично, INPUT_ARRAY[1] на INPUT02;таким образом, эта замена использует нулевое время и нулевую мощность во время выполнения.

Более того, когда компилятор C видит INPUT_ARRAY[1] в предварительно обработанном коде, он добавляет 1 во время компиляции к базовому адресуINPUT_ARRAY.Следовательно, вы получаете максимальную эффективность во время выполнения.

По общему признанию, если вы вручную выключите оптимизатор компилятора C, как с опцией -O0 GCC, то вполне возможно, что компилятор будет генерировать код сборкидобавить 1 во время выполнения.Так что не делайте этого.

Единственное вероятное исключение из вышесказанного - случай, когда базовый адрес INPUT_ARRAY был неизвестен компилятору во время выполнения, вероятно, потому что INPUT_ARRAY был динамически выделенв куче (что не имеет большого смысла для адресации устройств), но, скорее всего, потому, что базовый адрес INPUT_ARRAY настраивался во время загрузки через регистры конфигурации устройства.Это делают некоторые аппаратные средства, но если это делает ваш компьютер, то именно поэтому ваша MCU (или MPU) в первую очередь использует режим косвенной адресации со смещением индекса.Хотя этот режим включает целочисленную арифметическую единицу MCU, [a] режим не умножается (умножение является энергоемкой операцией);и, [b] в любом случае, режим является таким нормальным, часто используемым режимом, что MCU неизменно предназначены для его эффективной поддержки - возможно, не так эффективно, как предварительно вычисленная прямая адресация, но настолько эффективно, насколько можно разумно ожидать для такого использования.Изготовитель MCU знает, что выводы устройства - это то, что вам нужно решать.Инженер, который спроектировал ваш MCU, будет отдавать приоритет созданию максимально возможного косвенного режима со смещением индекса по этой и другим причинам.(Возможно, вы все еще можете обмануть вопрос, чтобы сэкономить несколько миллиджоулей с помощью самоизменяющегося кода, если ваш MCU даже допустил это; но, как инженер, вы бы пожалели об обмане, я подозреваю, если безопасность и ремонтопригодность не были проблемойдля вас. Проблема, вероятно, не является большой проблемой. Непрямая адресация со смещением индекса является обычной техникой, когда базовый адрес остается неизвестным до времени выполнения. Если вам действительно нужно сохранить этот последний миллиджоуль, тов любом случае вы, возможно, не используете компилятор C для внутреннего цикла вашего кода, но, возможно, это код сборки вручную.)

Я подозреваю, что было бы полезно попросить компилятор выдать код сборки для проверки.Я не знаю, какой компилятор вы используете, но если вы использовали GCC, то gcc -S myfile.c.

...