Полезные инструкции
Даже если вы не пишете на языке ассемблера, просматривайте иногда инструкции ядра: среди них можно отыскать интересные. При этом не все эти инструкции доступны напрямую синтаксисом Си, но их можно вызывать как intrinsic-функции (эти обертки содержаться в библиотеке CMSIS). Такие функции могут быть полезны при обработке данных и заменять целые участки кода. Рассмотрим реализацию алгоритма изменения порядка следования битов справа налево на языке Си.
// Bit Twiddling Hacks, https://graphics.stanford.edu/~seander/bithacks.html
uint32_t swap_word(uint32_t word) {
// swap odd and even bits
word = ((word >> 1) & 0x55555555) | ((word & 0x55555555) << 1);
// swap consecutive pairs
word = ((word >> 2) & 0x33333333) | ((word & 0x33333333) << 2);
// swap nibbles ...
word = ((word >> 4) & 0x0F0F0F0F) | ((word & 0x0F0F0F0F) << 4);
// swap bytes
word = ((word >> 8) & 0x00FF00FF) | ((word & 0x00FF00FF) << 8);
// swap 2-byte long pairs
word = ( word >> 16 ) | ( word << 16);
return word;
}
Здесь выполняется много операций — компилятор создаст целую портянку ассемблер-команд. Когда потребуется перевернуть сотни или тысячи чисел, выполнение займет изрядное количество времени. В действительности достаточно воспользоваться одной инструкцией процессора, имеющейся в ядре Cortex-M3, которая обернута в функцию __RBIT
в файле core_cmInstr.h
:
a = __RBIT(a);
Список подобных инструкций можно найти в документации ARM.
>Вопрос 48. Какой тип целочисленной переменной лучше всего СПОЛЬЗОВАТЬ в микроконтроллере PIC24 и почему?
Здравствуйте.
Мучаю STM32F030F4P6 и изучаю вашу книгу.
Замерял сегодня скорость выполнения вышеприведённых циклов на разных оптимизациях кода O1 O2 O3.
И у меня получилось что цикл
for (i = 0; i < 1000000; i++) {} выполняется на любой оптимизации за 4800 микросекунд
цикл for ( i = 1000000; i != 0; i—){} выполняется за 4800 микросек. только на оптимизации O1 . При оптимизации O2 и O3 он выполняется за 10800 микросекунд.
цикл
n = 1000000;
do {
// code here
} while (—n != 0); на любой оптимизации выполняется за 10800 микросекунд
может это связано с компиляцией и оптимизацией именно для данного чипа.
но лучше я буду писать for (i = 0; i < 1000000; i++){}
Взял осциллограф и всё перепроверил. Оказалось что у меня таймер переполнялся.
Думаю что мои коменты публиковать не нужно )