[uquote="ARV",url="/forum/viewtopic.php?p=4704614#p4704614"]Всё-таки двойные стандарты... HAL ругают за избыточность, а ведь там всего лишь все "функции", не задумываясь, проверяют все-все-все на допустимость...[/uquote]Причём тут проверка на допустимость? Функция должна правильно работать при всех значениях, которые можно подать ей на вход. Правильная работа функции это главное. Оптимизация это последний шаг. Вон
a5021 дооптимизировался - наплевал на инициализацию счётчика и получил, что задержка может скакать до 1 мс в минус.
Что вы собрались оптимизировать в функции, которая в блокирующем режиме ничего не делает? Одну ассемблерную команду зажали пожертвовав функционалом? Это проблема!
Можно, например, ограничить этой функции параметр на этапе компиляции, но так его нельзя будет менять в рантайме.
Код: Выделить всё
template <uint32_t ms>
void Delay()
{
static_assert(ms>0, "Wrong ms");
SysTick->VAL = SysTick->LOAD;
auto ms_ = ms;
while(ms_ -= SysTick->CTRL >> SysTick_CTRL_COUNTFLAG_Pos);
}
Мы сильно ограничили функционал и не приобрели ничего взамен, так как в константном применении компилятор сам бы выкинул проверку.
"Преждевременная оптимизация — корень всех зол " - Д.Кнут.
Добавлено after 37 minutes 1 second:
Кстати, в первоначальном варианте от
a5021 эта проверка тоже есть, просто она не бросается в глаза. А когда я написал так чтобы она стала очевидна и при нуле работала быстрее это вызвало протест. Почему?
Код: Выделить всё
// Можно её скрыть так
static void Delay(uint32_t ms)
{
SysTick->VAL = SysTick->LOAD;
while(ms)
ms -= SysTick->CTRL >> SysTick_CTRL_COUNTFLAG_Pos;
}
// Или так
static void Delay(uint32_t ms)
{
SysTick->VAL = SysTick->LOAD;
for(uint32_t i=ms; i; i -= SysTick->CTRL >> SysTick_CTRL_COUNTFLAG_Pos);
}
Для оптимизирующего компилятора это всё будет одно и то же.
Добавлено after 42 minutes 26 seconds:
[uquote="a5021",url="/forum/viewtopic.php?p=4704154#p4704154"]
Код: Выделить всё
DELAY_MS(500);
080001E4 LDR R3, [R4, #16]
080001E6 MOV.W R3, #0x01F4
080001EA LDR R2, [R4, #16]
080001EC SUBS.W R3, R3, R2, LSR #16
080001F0 BNE 0x080001EA
На мой взгляд и придраться не к чему. А на ваш?[/uquote]А на мой есть. Сложная 32-битная команда вычитания. Можно от неё избавиться.
Код: Выделить всё
static void Delay(uint32_t ms)
{
if(ms>0)
{
SysTick->VAL = SysTick->LOAD;
while(ms -= *((volatile uint16_t *)&SysTick->CTRL+1) );
}
}