Принудительная вакцинация вторым умножением, максимальный изврат: 40 байт на функцию, 7 тактов на цикл. https://godbolt.org/z/c1MYarv43 Без оптимизации -Os - второе умножение не появляется.
Разве L151 это М0? Да нет, сейчас перепроверил: все stm'ки, на которых я могу протестировать - F100, F103, L151 - относятся к М3.
Изначально Eddy_Em просил потестить на F0(M0), у тебя таких нет, потому появился тест [только] для L151(M3), я же написал, что на M0 функция с делением и взятием остатка будет медленно работать и на требование предоставить доказательства потестил на G0(M0+). Нигде не звучало, что L151 - это M0, сказано было, что L151 - это тоже STM32. Все трое обсуждали STM32, двое конкретно говорили про ядро M0 и все было хорошо пока не оказалось, что тесты оказывается нужны для AVR. Не буду говорить за других, но лично я не настолько прозорливый
COKPOWEHEU писал(а):
А в 2.7 раза это сколько в тактах? Может, там как и в AVR десять тысяч тактов и оба варианта годятся только отладочную информацию раз в вечность передавать. То есть не "данные для любознательных" закопаны под спойлер, а просто какие-то сырые данные без пояснений.
Спор был про скорость, а не нужность, числа на печать выводили и на 8051 исполняющих инструкции за 12 тактов, что уж говорить про 32-х битные мк c 32-х битным умножением разгоняющиеся до 140MHz. И вообще информация про 2.7 раза уже устарела, новый рекорд для M0 - 6.2 раза вот с такой функцией деления:
Проверяй ещё раз, твоё умножение требует сдвига на 35, ну или на 3 в старшем регистре. Хотя можно умножать на число не требующее дополнительной обработки результата. И я его нашёл 429496730UL.
А если расфигачить STM32 на uint128_t? ☺ Да не, чего ходить вокруг да около? Давайте операции через uint256_t делать!!! Вай, да: на современных процах с AVX2 и uint512_t реализовать не проблема. Давайте ими насиловать 32-битные МК!
_________________ Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда. Я на гитхабе, в ЖЖ
Reflector, подозреваю, что уж такие навороченные, но таки "M" никому нафиг не нужны будут! Уж дешевле тогда "A" взять, поставить нормальный линукс, да работать! А в качестве рилтайма по-старинке использовать те же самые M0 или M3.
_________________ Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда. Я на гитхабе, в ЖЖ
подозреваю, что уж такие навороченные, но таки "M" никому нафиг не нужны будут!
У M55 просто этот MVE есть, ну и ядро новое Armv8-M с небольшим количеством новых инструкций, а в остальном M7 так самым производительным и остался и до подорожания китайцы 480MHz H750 по $4-5 продавали и его очень даже брали, я, например
Проверяй ещё раз, твоё умножение требует сдвига на 35, ну или на 3 в старшем регистре
Несколько раз перечитал сообщение, но так и не понял что вы хотите. Что именно проверять, о каком умножении речь?
Цитата:
Изначально Eddy_Em просил потестить на F0(M0), у тебя таких нет, потому появился тест [только] для L151(M3)
Нет, тест появился не из-за EddyEm, тест появился, поскольку я подобными функциями пользуюсь, и было интересно узнать насколько они лучше или хуже альтернатив.
Цитата:
Спор был про скорость
Так для вас это всего лишь спор? Соревнование на самый быстрый код? Меня-то вопрос интересует в практическом смысле: стоит ли использовать и для каких задач.
Нет, тест появился не из-за EddyEm, тест появился, поскольку я подобными функциями пользуюсь, и было интересно узнать насколько они лучше или хуже альтернатив.
Появились тесты из-за Eddy_Em, не из-за Eddy_Em или частично из него - это в принципе недоказуемо и уже только поэтому не существенно. Я описывал последовательность событий когда шло обсуждения тестов для STM32 и подключившись к обсуждению я говорил о них же, делая акцент на том, что на M0, которые интересуют Eddy_Em, функция с делением и взятием остатка будет работать медленно, что в последствии и было убедительно доказано. Ни о каких AVR в той череде постов не говорилось и, соответственно, ни к каким постоянным попыткам извернуться и съехать с AVR на M0 я не причастен И да, если бы мне написали, что моя функция работает в 2.7 раза медленнее, то я бы определенно разобрался в чем там дело, а когда если спойлер и открыл, то сразу его и закрыл, то можно говорить что угодно, но степень заинтересованности налицо
COKPOWEHEU писал(а):
Так для вас это всего лишь спор? Соревнование на самый быстрый код? Меня-то вопрос интересует в практическом смысле: стоит ли использовать и для каких задач.
Это был спор по факту. Можно сказать и соревнование на самый быстрый или лучший код тоже. У многих есть подобные функции, после таких обсуждений кто-то пересмотрит подходы, код ускорит, уменьшит, устранит возможные ошибки и продолжит его использовать на практике.
Ну вот я глянул, что производительность деления uint32_t и умножений/сдвигов uint64_t не очень-то сильно отличается. Да, если нужно будет многократно делить на константы, можно попробовать оптимизировать через умножения и сдвиги. А в отдельных случаях, наверное, можно и не волноваться. Еще есть деления вроде как на константу, но она берется в рантайме, а не вычисляется компилятором. Скажем, вычисление температуры:
Код:
int32_t getMCUtemp(){ // return MCU temperature (degrees of celsius * 10) int32_t ADval = getADCval(2); int32_t temperature = (int32_t) *TEMP30_CAL_ADDR - ADval; temperature *= (int32_t)(1100 - 300); temperature /= (int32_t)(*TEMP30_CAL_ADDR - *TEMP110_CAL_ADDR); temperature += 300; return(temperature); }
А в вычислении Vdd наоборот: константа делится на изменяющееся число:
А в случае, если я захочу перевести ADU в Вольты, придется минимум два деления использовать.
_________________ Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда. Я на гитхабе, в ЖЖ
AVI-crak, gcc не зря когда заменяет деление на 10 сдвигает на 35 бит, простейший тест на пк обнаруживает тьму ошибок:
Ок, животина оказалась бракованной, пришлось пристрелить. Хотя выглядело очень красиво. Вывод из всего этого безобразия - нужно писать максимально просто.
Ну вот я глянул, что производительность деления uint32_t и умножений/сдвигов uint64_t не очень-то сильно отличается.
Ну если в 12 раз - это не "очень-то", то наверное. Cortex-M4: Так же как тут некоторые и между ARM и AVR разницы не видят, также для кого-то "в 12 раз" - это "не сильно отличаются".
Последний раз редактировалось jcxz Вс окт 24, 2021 13:40:45, всего редактировалось 1 раз.
Ну вот я глянул, что производительность деления uint32_t и умножений/сдвигов uint64_t не очень-то сильно отличается.
В целом да, но если взять мою последнюю функцию деления на 10, которая табличная и потому можно обойтись без 64 бит, то она на M0 отрабатывает всегда за 29 тактов, в то время как обычное деление медленнее и при небольших числах, а если делить максимальное 32-х битное значение, то уже будет 225 тактов...
Ну если в 12 раз - это не "очень-то", то наверное. Cortex-M4:
Для M4 и напрягаться особо не нужно, компилятор обычно сам все делает, а M0 не только при делении на константы косячит, помню всякие аналоги CLZ там тоже были в разы медленнее самописных.
Я верю своим глазам, а не рекламациям! А глаза мне показали в тесте Reflector разницу всего в полтора раза между делением uint32_t и умножением/сдвигами uint64_t. И при чем здесь M4, когда мы обсуждаем M0, у которого нет аппаратного деления? Что до М4, то приведенная таблица наглядно показывает: нет смысла на таком крутом ядре городить всякие умножения/сдвиги, когда реализация деления в среднем займет всего лишь 7 тактов! А на перемещение данных между регистрами, умножения и сдвиги уйдет не меньше!
_________________ Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда. Я на гитхабе, в ЖЖ
Я верю своим глазам, а не рекламациям! А глаза мне показали в тесте Reflector разницу всего в полтора раза между делением uint32_t и умножением/сдвигами uint64_t.
Тесты на реальном железе подтверждают данные таблицы. Достаточно запустить отладчик и посмотреть. IAR, CM4: Смотрим на строчку "CCSTEP".
нет смысла на таком крутом ядре городить всякие умножения/сдвиги, когда реализация деления в среднем займет всего лишь 7 тактов!
Всегда имеет смысл писать ПО, работающее быстрее. Даже если разница всего в несколько %. А когда разница в 7 раз(!), то тут даже вопроса не возникает - это должно быть очевидно.
PS: Да, и в реальных программах, работающих в реал-тайм, смотрят не на "среднее по больнице", а на худший случай (максимальное время выполнения). Т.е. - не 7 тактов, а 12 тактов.
Если аппаратного деления нет, то разница будет ещё больше, кэп. Уже видимо - во много десятков раз. Или ещё больше.
На M0 не только деления нет, но и длинного умножения, потому для деления на 10 через умножение получаем порядка 60-ти инструкций и все они будут выполняться даже если нужно 10 на 10 поделить.
И да, если бы мне написали, что моя функция работает в 2.7 раза медленнее, то
...то, учитывая уже имеющиеся данные, логично предположить либо ошибку эксперимента, либо особенность компилятора, либо что-то еще. Потому что на двух более выраженных крайностях особой разницы нет. Вы этого не сделали.
Цитата:
а когда если спойлер и открыл, то сразу его и закрыл, то можно говорить что угодно, но степень заинтересованности налицо
Да понял я , что вам результат не интересен, раз вы ни экспериментальных данных толком не привели, ни выводов, ни ввопросе разобраться не попытались - откуда такая разница. Ну не хотите и ладно, свой вывод я озвучил: разница в десяток процентов на чловеко-читаемом выводе несущественна.
На M0 не только деления нет, но и длинного умножения, потому для деления на 10 через умножение получаем порядка 60-ти инструкций и все они будут выполняться даже если нужно 10 на 10 поделить.
Уверены? Что-то многовато как-то... Проверил (в наличии у меня M0 нет), поэтому под симулятором. Написал такую функцию:
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 12
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения