STM32 новичку в ARM что к чему

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Собутыльник Кота
Аватара пользователя
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01

Сообщение Eddy_Em »

VladislavS, у него не знания, а "магия".
Я не собираюсь использовать то, чего не в силах понять.
И про кресты я уже сказал: это — не язык программирования, а какой-то садомазо…
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
Контактная информация:
Реклама
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="Eddy_Em",url="/forum/viewtopic.php?p=3922001#p3922001"]хватит уже со своими крестами! Я в эту [censored] лезть не собираюсь![/uquote]
При чем тут кресты... Смотри, запускаю на STM32G0, там нет умножения 32*32->64, потому оно эмулируется:

Код: Выделить всё

volatile uint32_t val = 10000;
const uint32_t k = (1 << 20) * 0.028261 + 0.5;
uint32_t out = (uint64_t)k * val >> 20; // -> 282
Если числа относительно небольшие, то во многих случаях можно обойтись без приведения к uint64_t. А у тебя будет так:

Код: Выделить всё

volatile uint32_t val = 10000;
const uint32_t N = 13;
const uint32_t D = 46 * 10;
uint32_t out = val * N / D; // -> 282
Первый код выполняется примерно за 70 тактов, второй - за 100.
Реклама
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

Reflector писал(а):При чем тут кресты...
При том, ушли от понятной формулы

Код: Выделить всё

 uint8_t value = ((24 * h / 17) / 60) % 6;
не понятно к какой, и что бы что то поменять надо заново пересчитывать, так?
Давайте поменяем и посчитаем:

Код: Выделить всё

uint8_t value = ((25* h / 18) / 59) % 7;
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="Dimon456",url="/forum/viewtopic.php?p=3922170#p3922170"]При том, ушли от понятной формулы

Код: Выделить всё

 uint8_t value = ((24 * h / 17) / 60) % 6;
[/uquote]
Изначально смысл в том, что h нужно умножить на понятные 360/256, а непонятные 24/17 появились в следствии оптимизации для 8-ми биток. Но на ARM это не оптимизация, а ее противоположность, я же напротив код именно ускорил, при этом он также стал менее читаем, точно как и оригинал, что совсем не удивительно. Если просто заменить 24 и 17 на 360 и 256, то будет и понятнее, и быстрее, т.к. вместо деления будет сдвиг.
Реклама
Эиком - электронные компоненты и радиодетали
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2081
Зарегистрирован: Пт май 31, 2013 17:14:38
Откуда: Украина, Винница

Сообщение Ярослав555 »

такой вопрос - где-то можно посмотреть как зависит время записи на флеш от питания МК? так получилось что имею почти идентичные платы. и оказалось что на одной из них стирание страницы 128kB уперлось в ватчдог (видимо на грани работало). Увеличив период ватчдога я убрал глюк, но интересно было узнать почему так. МК идентичные, единственная разница что вижу - отстающий имеет на 30мВ ниже питание.
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

К вопросу о том зачем нужны современные компиляторы, языки программирования и их стандарты. Есть у меня в библиотеке функция, которая считает количество установленных в числе бит.

Код: Выделить всё

constexpr auto countSetBits(uint32_t value)
{
  auto bits = 0;
  while (value)
  {
    value &= value - 1;
    bits++;
  }
  return bits;
}
Попробовал как она работает на С (убрав синтаксис С++, естественно).
СпойлерИзображение
c18_popcount.png
(64.45 КБ) 160 скачиваний
А вот так она у меня в библиотеке на С++ работает. Вычисляется на этапе компиляции, если аргумент позволяет. А он, как и в прошлом примере на С, позволяет.
СпойлерИзображение
c++17_popcount.png
(55.5 КБ) 158 скачиваний
Господа из комитета по стандартизации посмотрели на всё это безобразие и сказали: "Классный у тебя алгоритм, давай его в стандарт С++20 введём. А ты ещё что-нибудь полезное программируй".
СпойлерИзображение
c++20_popcount.png
(40.45 КБ) 150 скачиваний
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01

Сообщение Eddy_Em »

VladislavS, на компе можно просто popcnt вызвать же!
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

Изображение
Topic.png
(25.65 КБ) 741 скачивание
И на этапе компиляции.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Я так и не понял восторгов: если программист вызывает функцию для того, чтобы посчитать биты в заранее известной константе, разумно ли вводить это в стандарт? Или просто константы будут запрещены?
Что-то я не понимаю восторга: вплоть до 64-битных констант число единичных бит вычисляется не-двоешником практически в уме...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="ARV",url="/forum/viewtopic.php?p=3924331#p3924331"]Я так и не понял восторгов: если программист вызывает функцию для того, чтобы посчитать биты в заранее известной константе, разумно ли вводить это в стандарт? Или просто константы будут запрещены?[/uquote]
Такая функция используется в либе портов, допустим есть такой список:

Код: Выделить всё

PinList<PA5, PA6, PA7, PB10, PA0, PA1> pins;
Будет найдено две последовательности, в обoих пины идут в обратном порядке: PA0, PA1 и PA5, PA6, PA7. Для каждой последовательности находятся маски 0x03 и 0xE0, если в маске больше двух бит, то будет использована реверсная инструкция RBIT, иначе ее применение не оправдано. Все это происходит на этапе компиляции и никакие константы заранее не известны :)
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

мда... занятно.

этак скоро дисциплину "программирование" в ВУЗах преподавать перестанут, ибо эфект обучения будет нулевой: достаточно функцию вычисления корней квадратного уравнения (классика!) обозвать constexpr, и получить на выходе что-то типа mov ax, 12 ret вместо всего алгоритма... :)))
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="ARV",url="/forum/viewtopic.php?p=3924331#p3924331"]посчитать биты в заранее известной константе, разумно ли вводить это в стандарт?[/uquote]Во-первых, константа может быть неизвестна, а быть результатом сложных преобразований типов и данных. Во-вторых, это может быть и не константа вовсе, тогда компилятор будет сам разбираться что с ней делать - вызовет ли что-то похожее на мою функцию в рантайме или у процессора есть специальная инструкция для этого. Главное, что мне не надо думать об этом, а думать о бизнеслогике.

Добавлено after 8 minutes 37 seconds:
[uquote="ARV",url="/forum/viewtopic.php?p=3924351#p3924351"]достаточно функцию вычисления корней квадратного уравнения (классика!) обозвать constexpr, и получить на выходе что-то типа mov ax, 12 ret вместо всего алгоритма... :)))[/uquote]Если на входе функции константные данные, то результат её "известен" до запуска программы. Так зачем тратить время программы на её выполнение? И C++ позволяет переложить это на плечи компилятора уже сейчас, а не "скоро".
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

VladislavS писал(а):И C++ позволяет переложить это на плечи компилятора уже сейчас, а не "скоро".
давным-давно в другой ветке я говорил, что мечта всех программистов заключается в том, чтобы было можно написать "сделай мне хорошо" - и это вся программа, а компилятор разберется, что именно будет хорошо... но это оффтоп и я больше не буду
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01

Сообщение Eddy_Em »

Надеюсь, таки инструкцию popcnt и ей подобные внедрят в более свежие армы. Уж очень она хороша!
А еще инструкции, которые выдают самый старший единичный бит и самый младший единичный бит.
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
Контактная информация:
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="Eddy_Em",url="/forum/viewtopic.php?p=3924368#p3924368"]А еще инструкции, которые выдают самый старший единичный бит и самый младший единичный бит.[/uquote]
Уже есть CLZ, предварительно можно биты развернуть при помощи RBIT.
Друг Кота
Аватара пользователя
Сообщения: 3386
Зарегистрирован: Пн окт 11, 2010 19:00:08

Сообщение Мурик »

VladislavS писал(а):А вот так она у меня в библиотеке на С++ работает. Вычисляется на этапе компиляции, если аргумент позволяет.
В большинстве случаев не позволяет. Покажите что сгенерирует компиль если значение не константно, а например считывается из порта.

И думаю вы знаете что const в Си вовсе не делает переменную константой. Попробуйте в Си-коде заменить const на #define.
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="Мурик",url="/forum/viewtopic.php?p=3924574#p3924574"]В большинстве случаев не позволяет. Покажите что сгенерирует компиль если значение не константно, а например считывается из порта.[/uquote]
В том коде не может быть не константа - это будет ошибка компиляции.
Стоп, это другой пример, я думал это все еще про либу портов :) Тогда развернется в приличную функцию, но она такой в любом случае будет...
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 342
Зарегистрирован: Чт ноя 21, 2013 14:05:26
Откуда: Україна

Сообщение DJZEM »

Ох уж эти замудреные дядьки ))
Контактная информация:
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

Бонус для Eddy_Em :)
Спойлер

Код: Выделить всё

uint32_t getMinPriority(uint32_t value)
{
#ifdef __ARM_ARCH_6M__
	static const uint8_t table[32] = { 0, 1, 2, 24, 3, 19, 6, 25, 22, 4, 20, 10, 16, 7, 12, 26, 31, 23, 18, 5, 21, 9, 15, 11, 30, 17, 8, 14, 29, 13, 28, 27 };

	value = (value & -value) * 0x04D7'651F;
	return table[value >> 27];
#else
	return  __CLZ(__RBIT(value));
#endif
}

getMinPriority(0x0F00'00F0); // 4
getMinPriority(0x0F00'0000); // 24
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="Мурик",url="/forum/viewtopic.php?p=3924574#p3924574"]
VladislavS писал(а):А вот так она у меня в библиотеке на С++ работает. Вычисляется на этапе компиляции, если аргумент позволяет.
В большинстве случаев не позволяет.[/uquote]Попытался вспомнить весь свой программистский опыт и не вспомнил когда бы я эту функцию применял на неконстантных данных. Наиболее близко это бит чётности в UART, который считается аппаратно.

[uquote="Мурик",url="/forum/viewtopic.php?p=3924574#p3924574"]Покажите что сгенерирует компиль если значение не константно, а например считывается из порта.[/uquote]Будет такой же вызов функции, как под первым спойлером. Природу не обманешь.

[uquote="Мурик",url="/forum/viewtopic.php?p=3924574#p3924574"]И думаю вы знаете что const в Си вовсе не делает переменную константой.[/uquote]Посмотрите ещё раз листинг. Самая натуральная константа, лежит себе в сегменте кода. Не константа будет вот так
СпойлерИзображение
C0.png
(64.5 КБ) 106 скачиваний
[uquote="Мурик",url="/forum/viewtopic.php?p=3924574#p3924574"]Попробуйте в Си-коде заменить const на #define.[/uquote]Легко. Ничего это в данном случае не меняет.
СпойлерИзображение
C1.png
(57.12 КБ) 100 скачиваний
Если честно, другие компиляторы всё же могут вычислить эту функцию в С режиме в компайлтайме. Но вот конкретно для ARM на Compiler Exploer вот так. Увы и ах, он льёт воду на нашу мельницу :)

Надеюсь, предложения саму функцию заменить макросом не последует?

Добавлено after 10 minutes 17 seconds:
[uquote="Reflector",url="/forum/viewtopic.php?p=3924614#p3924614"]Бонус для Eddy_Em :)[/uquote]Опять ты со своими крестами. Он апострофы не понимает :)

Добавлено after 2 minutes 55 seconds:
[uquote="Reflector",url="/forum/viewtopic.php?p=3924614#p3924614"]

Код: Выделить всё

return __CLZ(__RBIT(value));
[/uquote]Не знаешь, GCC так и не научили __RBIT в компайлтайме считать?
Ответить

Вернуться в «ARM»