Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

Re: Лучше не использовать типы char в stm32?

Вс окт 24, 2021 16:21:02

Уверены? Что-то многовато как-то...

Re: Лучше не использовать типы char в stm32?

Вс окт 24, 2021 18:50:25

https://github.com/bobbl/libaeabi-cortexm0
Человечеще спецом заморачивался в оптимизации cortexm0, и мне кажется этот код уже включён в GCC. Потому как на выхлопе очень похожее получается.
Так легко можно увидеть вложенные циклы на делении __aeabi_uidiv ( u32=u32/u32).
И отсутствие циклов на умножении __aeabi_lmul (u64=u64*u64).

Re: Лучше не использовать типы char в stm32?

Чт окт 28, 2021 00:02:35

Вот вы тут все про оптимизацию, а я уже второй вечер под пивасик выдумываю, как бы реализовать рамп шаговика! Точней, у меня на одном STM32F072 контроллер трех шаговых двигателей. Они могут быть как с обратной связью (квадратурный оптический или магнитный энкодер), так и без нее. И самое неприятное в том, что каждые несколько миллисекунд нужно будет в состоянии разгона или торможения заново вычислять ARR пинающего драйвер ШД таймера! И там, естественно, есть деление на некоторое число: ARR=FREQ/V, а V вычисляется каждый раз как V+=dV (или V-=dV на стадии торможения). Причем, если есть энкодер, на стадии разгона нужно еще проверять, не застрял ли вал вообще (если застрял - снижаем скорость, если снизили до минимальной и все равно кирдык — сигналим: "ахтунг") и нет ли проскальзываний (если есть, то скорость пока не увеличиваем)... Ну и в каждом прерывании таймера ШД нужно проверять концевики.
Трындец, сколько вычислений.
Хотя, с другой стороны, это будет от силы тактов 200-300. Т.е. меньше десятка микросекунд. И лень говорит: "а может, нафиг оптимизации? И так сойдет!"

Добавлено after 1 hour 15 minutes 24 seconds:
Японский городовой! Проблеме построения рампа столько статей посвящено, что задолбаешься читать!!! И у всех более-менее одно и то же (сам подобный алгоритм и нарисовал себе), разве что некоторые особо упорные (или упоротые?) китайцы такой математики накидали, что никакой Cortex-M0 не осилит!

Re: Лучше не использовать типы char в stm32?

Пт ноя 05, 2021 14:56:44

Как сократить операцию сравнения? cmp
https://godbolt.org/z/eT5j7nP3W

Re: Лучше не использовать типы char в stm32?

Вт ноя 09, 2021 01:20:40

https://godbolt.org/z/sx7ernxjj
Деление uint64_t на 10 за 68 тиков, __aeabi_uldivmod из GCC жуёт цифры аж 269 тиков.
Код:
#define MAGICDIV  3435973837UL
const uint32_t divu64_dat[]={
  0x00000000, 0x19999999, 0x33333333, 0x4CCCCCCC, 0x66666666,
  0x80000000, 0x99999999, 0xB3333333, 0xCCCCCCCC, 0xE6666666,};
 
union divrev {uint64_t w64;uint32_t w32[2];}rev;
 
/// 68 cpu clock (DWT->CYCCNT)
uint64_t divu64_10 (uint64_t value, uint8_t *residue)
{
  uint32_t nex;
  union divrev rev;
  union divrev res;
  rev.w64 = value;
  res.w32[1] = ((uint64_t)rev.w32[1] * MAGICDIV >> 35);
  nex = rev.w32[1] - res.w32[1] * 10;
  rev.w32[1] = nex;
  rev.w64 -=  (uint64_t)divu64_dat[nex] * 10;
  res.w32[0] = divu64_dat[nex];
  if (rev.w32[1] != 0) {
          rev.w64 -= (uint64_t)divu64_dat[1] * 10;
          res.w64 += (uint64_t)divu64_dat[1];
          };
  nex = ((uint64_t)rev.w32[0] * MAGICDIV >> 35);
  res.w64 += (uint64_t)nex;
  *residue = rev.w32[0] - nex * 10;
  return res.w64 ;
};
Последний раз редактировалось AVI-crak Вт ноя 09, 2021 16:27:46, всего редактировалось 1 раз.

Re: Лучше не использовать типы char в stm32?

Вт ноя 09, 2021 10:39:59

А какие проблемы на M7? https://godbolt.org/z/71jsT3xM6
На M0 что получится?

Re: Лучше не использовать типы char в stm32?

Вт ноя 09, 2021 10:43:33

Деление uint64_t на 10 за 68 тиков

Код:
for(uint64_t i = -1; i > 0xFFFF'FFFE'0000'0000; i--)
{
    if (i / 10 != divu64_10(i))
        printf("Error: %llu, %llu, %llu\n", i, i / 10, divu64_10(i));
}

>> Error: 18446744069414584319, 1844674406941458431, 1844674406511961702
>> Error: 18446744069414584318, 1844674406941458431, 1844674406511961702
>> Error: 18446744069414584317, 1844674406941458431, 1844674406511961702
>> Error: 18446744069414584316, 1844674406941458431, 1844674406511961702

Re: Лучше не использовать типы char в stm32?

Вт ноя 09, 2021 10:51:10

Reflector, естественно, там переполнение будет. Чтобы с uint64_t работать, нужно промежуточные результаты в uint128_t хранить. А это уж совсем оверхед для микроконтроллера.
Подозреваю, в оригинале все-таки был пример деления uint32_t, а uint64 случайно скопипастился.
Но я бы и с uint32_t проверил: нет ли переполнения. Помнится, у кого-то в алгоритме был сдвиг вправо на 35 — это стопудово работать не будет!

Re: Лучше не использовать типы char в stm32?

Вт ноя 09, 2021 10:55:27

Помнится, у кого-то в алгоритме был сдвиг вправо на 35 — это стопудово работать не будет!

Я приводил код с делением на 10/100/1000/1М, со сдвигами на 35 и т.д.. Быстро подобрал и проверил, потом оказалось gcc делает точно так же :) Длинное умножение на ассме для M0 тоже естественно проверил, пришлось STM32G0 разогнать до 140MHz и подождать минут 20...

Re: Лучше не использовать типы char в stm32?

Вт ноя 09, 2021 12:13:04

Reflector, а, дошло: при сдвиге на 35 теряются три младших бита, но они нам и так не нужны, т.к. мы же делим не по правилам округления, а отбрасывая всю дробную часть!

Re: Лучше не использовать типы char в stm32?

Вт ноя 09, 2021 12:25:37

при сдвиге на 35 теряются три младших бита, но они нам и так не нужны, т.к. мы же делим не по правилам округления, а отбрасывая всю дробную часть!

При делении на 10(или умножении на 0.1) результат поместится в 29 бит, т.к. это будет наблюдаться уже при делении на 8, потому 3 дополнительных бита можно использовать для более точных расчетов. Аналогично при делении на 1000 можно дополнительно задействовать 9 бит(2^9 = 512).

Re: Лучше не использовать типы char в stm32?

Вт ноя 09, 2021 16:30:14

>> Error: 18446744069414584319

Упс, GCC усиленно сокращает (uint64_t) операции до (uint32_t), подправил.

Re: Лучше не использовать типы char в stm32?

Вт ноя 16, 2021 01:03:36

Вот вы тут все про оптимизацию, а я уже второй вечер под пивасик выдумываю, как бы реализовать рамп шаговика!

Позавчера таки пришли разъемы, я их запаял вчера и сегодня пре-пре-альфу сделал. Еще полным-полно косяков, но без энкодера свободно крутит шаговик: ускоряет/замедляет. С энкодером чуть похуже: надо отладить алгоритм определения заклинивания, а то пока чуть пальцем нажал - и оно встало (вместо 24В подключил 12, да и вместо 1.7А на движок выдаю 600мА)!
Вот только с делениями оптимизировать нормально не вышло: каждые 10мс при разгоне/торможении нужно новое значение скорости вычислять. v=v₀ + a(t-t₀)/1000 (т.к. t измеряется в миллисекундах). А потом вычислять новое значение ARR: ARR = (((PCLK/(MOTORTIM_PSC+1)) / curspeed[i]) >> ustepsshift[i]) - 1; и проверять его на вхождение в интервал [99, 65535]. Поначалу я сделал минимальным ARR двойку, но процесс ускорения/торможения на высоких скоростях уж очень слух резал (таки получается, что вначале скорость падает вообще в 2 раза), а здесь квант в 1% — более плавно.

Как разберусь с движками, надо будет все остальное отладить по-человечески (особенно кучу сеттеров/геттеров всяких второстепенных). Да и протокол CAN я еще не проверял.

Re: Лучше не использовать типы char в stm32?

Вт ноя 23, 2021 18:01:52

Мама дорогая! printf на микроконтроллере!..
Вы туда еще malloc запихайте ради полного "Щассья".


А чем вам, собственно, не угодил printf? Стандартная СИшная функция, может быть реализована по разному для разных МК или приложений, но по-моему достаточно удобно использовать. Обеспечивает простую переносимость кода.

Да и malloc иногда полезен. Были у меня задачи, когда без него просто не получалось справиться.

Re: Лучше не использовать типы char в stm32?

Вт ноя 23, 2021 19:50:59

А чем вам, собственно, не угодил printf?

Оверхедом. Жутким оверхедом.
Стандартная СИшная функция

Ничуть она не сишная, она из glibc! Не существует "стандартной сишной функции printf"! Если что, вообще не существует стандартных сишных функций! Зато существует стандартная библиотека glibc, вот из нее-то эти функции и берутся.
Вот только никто не линкует прошивки микроконтроллеров с glibc! Для этого даже флаги специальные выставляются...
Да и malloc иногда полезен

Разве что если на МК есть MMU. Иначе malloc нафиг не нужен. Изврат это - вручную заниматься разделением памяти. Всегда есть шанс, что куча наткнется на стек, и получится незапланированный кирдык. А если резервировать для стека достаточно много, то приличный объем памяти вообще никогда не будет использован!

Re: Лучше не использовать типы char в stm32?

Ср ноя 24, 2021 05:17:42

Изврат это - вручную заниматься разделением памяти. Всегда есть шанс, что куча наткнется на стек, и получится незапланированный кирдык.

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

Re: Лучше не использовать типы char в stm32?

Ср ноя 24, 2021 09:39:46

А зачем тогда вообще аллокаторы рукожопить, если и так все хорошо работает?
Что до printf, я против printf из glibc, т.к. он полон оверхеда (например, на кой черт разбирать аргументы uint64_t, float и double на 32-битном МК без FPU?). Для вывода целых чисел можно нарисовать свой printf. Я же ограничиваюсь функциями void bufputchar(char c), добавляющей в буфер отправки 1 символ, void addtobuf(char *s), добавляющей в буфер строку, а также char *printu(uint32_t u), char *printi(int32_t i) и char *printuhex(uint32_t u), которые выдают строку с числом.

Re: Лучше не использовать типы char в stm32?

Ср ноя 24, 2021 09:40:36

Ничуть она не сишная, она из glibc!

Только не из glibc (гнутого), а из libc (любого). Но семейство printf в стандарт Си входит, от этого никуда не деться. Другое дело что ее реализацию можно не подключать и соответственно сэкономить килобайт флеша и сколько-то тактов.
Разве что если на МК есть MMU.

При чем здесь MMU? Я бы еще понял MPU - модуль защиты памяти. Но преобразование адресов как поможет?
Кстати, без MMU может быть даже безопаснее: софт может самостоятельно проверять допустимость полученного адреса даже если выделение прошло успешно.

Re: Лучше не использовать типы char в stm32?

Ср ноя 24, 2021 10:00:34

При чем здесь MMU?

При том, что без него вообще руки надо отрывать за использование аллокаторов!

Re: Лучше не использовать типы char в stm32?

Ср ноя 24, 2021 10:13:13

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