но почему то получается в этих реализациях бибилиотек c++ дополнительные накладные расходы предоставляют...
Потому что стандартная библиотека рассчитана на массивы произвольной длины и выполняет лишние проверки, которые для массива фиксированной длины 5 элементов не требуются.
Само собой. Я не зря перечислил еще ряд условий, которые должны соблюдаться.
эмм... ты же утверждал, что там будет указатель... что явно являлось неправдой.
Добавлено after 5 minutes 13 seconds: по своей сути -- если простым языком, то std::array в аргументах функции будет представлен будто локальный массив в теле функции... а данные которые должны быть в нем будут сразу подставлены в эту память. по этому нет никаких различий в случаях:
Само собой. Я не зря перечислил еще ряд условий, которые должны соблюдаться.
эмм... ты же утверждал, что там будет указатель... что явно являлось неправдой.
Нет, я утверждал, что там будет указатель в случае, если данная функция реализована в виде библиотеки и соблюдать C++ ABI Если хотите проверить, то соберите её с __declspec(dllexport)
Заголовок сообщения: Re: Хитрые, необычные алгоритмы и код
Добавлено: Чт дек 05, 2024 22:44:56
Первый раз сказал Мяу!
Зарегистрирован: Пн мар 18, 2024 22:04:17 Сообщений: 37
Рейтинг сообщения:0
ПростоНуб, ты сказал вот это:
Цитата:
Массив передается в функцию по указателю, поэтому просто обязан быть в памяти. А локальным переменным функции ничто не мешает быть регистровыми, что и использует компилятор.
-- но это неправда про массив... ни по какому указателю он не передается))) -- выше я указал как он обязан восприниматься. собственно как и ничего ему не мешает как и локальным переменным функции "располагаться на регистрах"...
STM32H7 на 550MHz, выполняющие 2 инструкции за такт, даже без нормального SIMD должны быть существенно быстрее вашего Xtensa с SIMD. И что прикажете делать? Какой из этих двух мк устарел? )
А можно еще узнать, почему Вы сравниваете STM32H7 с достаточно старым ESP32-S3, а не с ESP32-P4, имеющим на вооружении 8 128-битных векторных регистров и соответствующий набор SIMD инструкций?
Массив передается в функцию по указателю, поэтому просто обязан быть в памяти. А локальным переменным функции ничто не мешает быть регистровыми, что и использует компилятор.
-- но это неправда про массив... ни по какому указателю он не передается)))
А и раньше писал
safocl писал(а):
Если при компиляции целиком это и может быть заинлайнено или как-то оптимизировано, то в случае библиотечной функции, С++ ABI не позволяет передать массив, иначе, чем по указателю.
Могу посмеяться над голословным утверждением. Без данных тестирования, которое можно повторить и проверить, говорить об этом смысла не имеет. Возможны любые результаты. Например, в том же ffmpeg переход на SSSE3 дал прирост производительности некоторых функций в 40 раз, а на AVX-512 - в 94 раза.
Я находил статью на хабре с "вашими" median3 и median5, где так же говорилось, что с SSE будет быстрее, раза в 2, а не в 94 )
ПростоНуб писал(а):
Так что имея почти двукратный выигрыш в CoreMark, STM32H7 вполне может проиграть.
LX7 1 core at 240MHz: 613.86 CoreMark LX7 2 cores at 240MHz: 1181.60 CoreMark STM32H730: 2778 CoreMark Ага, почти в 2 раза )
А можно еще узнать, почему Вы сравниваете STM32H7 с достаточно старым ESP32-S3, а не с ESP32-P4, имеющим на вооружении 8 128-битных векторных регистров и соответствующий набор SIMD инструкций?
ESP32-P4 похоже еще только в виде семплов существует, на сайте даже документации нет, нашел поиском только Datasheet (Pre-release v0.1) )
-- в этом то и грусть -- ты же отнёс такое к моему случаю, где в аргументах передан std::array )))
Добавлено after 43 minutes 9 seconds: ну и кстати да -- подумалось, что вообще тест с неизменным массивом неактуален -- поскольку могут сильно кэшироваться данные... -- в общем нужны тесты в рабочей задаче -- как я и говорил изначально. немного приблизить в сторону реальности может помочь использование std::launder -- но он только позволит раскэшировать указатель, но не обязательно локальность данных в кэшах устранит от неизменяемого массива данных... однако, даже в таком случае вариант с std::array в аргументах работает на несколько порядков быстрее чем с указателем (который в варианте тестирования без std::launder кэшировался в том числе и по данным -- а поскольку в цикле тупо много раз одни и теже данные крутились давало такой эффект быстродействия).
Добавлено after 40 minutes 5 seconds: не... отмена -- енто нечаянно запхал std::launder в цикл отстающему... получается что одинаково... но снова же не анулирует потенциальной грусти в реальной задаче варианта с указателем.
Могу посмеяться над голословным утверждением. Без данных тестирования, которое можно повторить и проверить, говорить об этом смысла не имеет. Возможны любые результаты. Например, в том же ffmpeg переход на SSSE3 дал прирост производительности некоторых функций в 40 раз, а на AVX-512 - в 94 раза.
Я находил статью на хабре с "вашими" median3 и median5, где так же говорилось, что с SSE будет быстрее, раза в 2, а не в 94 )
Ради интереса тоже поискал. Нашел статью очень похожую, но с функциями на FORTRAN. https://habr.com/ru/articles/793388/ Цитирую: "Замена сортировки и поиска k-го элемента на простые минимаксные функции медианы для 3 и 5 элементов дала нам ускорение примерно в 50 раз." А с распараллеливанием вычислений: "На тестовых настольных компьютерах автора работу фильтра удалось ускорить в 130–160 раз." Видимо другая статья?
Так что имея почти двукратный выигрыш в CoreMark, STM32H7 вполне может проиграть.
LX7 1 core at 240MHz: 613.86 CoreMark LX7 2 cores at 240MHz: 1181.60 CoreMark STM32H730: 2778 CoreMark Ага, почти в 2 раза )
Во-первых, Вы писали STM32H7, а вовсе не STM32H730. Во-вторых, там в разных источниках по разному. Для STM32H730 я и 3324 встречал, а для ESP32-S3 официальные данные приводятся для выполнения кода из флеша, который доступен только по SPI и кешируется в IRAM. Установка CONFIG_ESPTOOLPY_FLASHMODE в QIO вместо DIO в некоторых случаях приводит к удваиванию производительности. Естественно, если вместо родного флеш модуля подключить внешний по четырем, а не двум SPI каналам.
Ради интереса тоже поискал. Нашел статью очень похожую, но с функциями на FORTRAN. https://habr.com/ru/articles/793388/ Цитирую: "Замена сортировки и поиска k-го элемента на простые минимаксные функции медианы для 3 и 5 элементов дала нам ускорение примерно в 50 раз." А с распараллеливанием вычислений: "На тестовых настольных компьютерах автора работу фильтра удалось ускорить в 130–160 раз." Видимо другая статья?
Статья та, нашли вы в ней не то )
Цитата:
Можно практически убедиться, что функция median3, использующая max и min (компилируемые один-в-один в машинные инструкции вроде vpmaxsd и vpminsd), действительно примерно вдвое быстрее, чем использующая if.
А функция поиска k-го элемента, даже без сортировки, там выглядит так: Спойлер
Код:
subroutine i4vec_frac ( n, a, k, frac ) implicit none
if ( n <= 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'I4VEC_FRAC - Fatal error!' write ( *, '(a,i8)' ) ' Illegal nonpositive value of N = ', n stop end if
if ( k <= 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'I4VEC_FRAC - Fatal error!' write ( *, '(a,i8)' ) ' Illegal nonpositive value of K = ', k stop end if
if ( n < k ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'I4VEC_FRAC - Fatal error!' write ( *, '(a,i8)' ) ' Illegal N < K, K = ', k stop end if
left = 1 iryt = n
do
if ( iryt <= left ) then frac = a(k) exit end if
ix = a(k) i = left j = iryt
do
if ( j < i ) then
if ( j < k ) then left = i end if
if ( k < i ) then iryt = j end if
exit
end if ! ! Find I so that IX <= A(I). ! do while ( a(i) < ix ) i = i + 1 end do ! ! Find J so that A(J) <= IX. ! do while ( ix < a(j) ) j = j - 1 end do
if ( i <= j ) then
t = a(i) a(i) = a(j) a(j) = t
i = i + 1 j = j - 1
end if
end do
end do
return end
Не верите, что вместе с поиском она может быть медленнее в 50 раз? ) И причем тут распараллеливанием вычислений на многоядерных процессорах? Без SSE что нельзя распараллеливать...
ПростоНуб писал(а):
Во-первых, Вы писали STM32H7, а вовсе не STM32H730.
Я писал про STM32H7 работающий на частоте 550MHz, без разницы какой. И он даже не самый быстрый, есть и 600MHz(3174 CoreMark).
ПростоНуб писал(а):
Во-вторых, там в разных источниках по разному. Для STM32H730 я и 3324 встречал, а для ESP32-S3 официальные данные приводятся для выполнения кода из флеша, который доступен только по SPI и кешируется в IRAM. Установка CONFIG_ESPTOOLPY_FLASHMODE в QIO вместо DIO в некоторых случаях приводит к удваиванию производительности. Естественно, если вместо родного флеш модуля подключить внешний по четырем, а не двум SPI каналам.
ESP32-S3 - медленный, это общеизвестно. Я брал для него данные из Datasheet и они там даже больше, чем в других источниках. При одинаковой частоте он даже M4 проигрывает, что уж про M7 говорить. Для H7 на офсайте написано.
1.The current chip version is V0.1. The functionalities of USB Serial JTAG are not available, which will be supported in the future chip revision.
2. The ADC on current samples is not calibrated, so the ADC calibration functionality is not available yet. The ADC will be calibrated on chips for mass production orders.
-- он не просто отделим -- он вообще никаким боком к языку программирования С++ не имеет отношения... сам видел... стандарты C++ не дадут соврать...
Добавлено after 9 minutes 13 seconds: ну тоесть тут конечно следует сделать замечание -- что именно этот ABI зависит от C++, но не наоборот -- что в нашем случае вообще незначимо и может опускаться -- поскольку мы обсуждали C++ код и его возможности.
1.The current chip version is V0.1. The functionalities of USB Serial JTAG are not available, which will be supported in the future chip revision. 2. The ADC on current samples is not calibrated, so the ADC calibration functionality is not available yet. The ADC will be calibrated on chips for mass production orders.
Для целей сравнения производительности без отладки по USB и без ADC вполне можно обойтись. Так что я не возражаю, если именно его Вы будете использовать для тестов.
-- он не просто отделим -- он вообще никаким боком к языку программирования С++ не имеет отношения... сам видел... стандарты C++ не дадут соврать...
Проблема в том, что единственная альтернатива ему - микросервисная архитектура. И как бы не эффективен был gRPC или MQTT, но динамическое связывание, невозможное без ABI, у них сильно выигрывает по производительности. Следующая проблема, что официальный стандарт C++ не фиксирует ABI. Отсюда, компилятор совсем не обязан поддерживать Itanium C++ ABI. Отсюда вытекает третья проблема, проброса через ABI данных и исключений. Пока данные POD типа - всё относительно просто. Но как только надо передавать не только POD типы или что-то делать с исключениями, нравится Вам это или нет, но на уровне кода нужно учитывать степень поддержки Itanium C++ ABI используемым компилятором, его версии и даже параметров оптимизации. Например, на тех проектах, с которыми я связан, проброс исключений через ABI категорически запрещен. Можно использовать код ошибки, можно optional<T> с обязательной реализацией семантик перемещения и копирования. Вариантов много, но каждый требует реализации его в коде. Так что, даже на МК, если недостаточно встроенной флеш памяти и нужно использовать внешнюю, например, SD-карту, ABI сразу становится весьма тесно связан с кодом и языком программирования. И если для C тут всё довольно просто, то на C++ открывается весь масштаб ограничений динамического связывания.
Вы опять затягиваете меня в области демагогии и догадок. Вот предоставьте результаты тестов и методику измерений - тогда продолжим.
Я сказал, что согласно автору статьи такие же median3/5 как у вас примерно в 2 раза быстрее при использовании SSE и это именно то, о чем там действительно говорится. Вы же выцепили из статьи фрагменты где речь идет о том, что эти median3/5 с SSE в 50 раз быстрее каким-то ДРУГИХ функций без SSE, а если распараллелить на разных ядрах, то и в 130–160 раз. И что? И ничего, чистая демагогия )
ПростоНуб писал(а):
Для целей сравнения производительности без отладки по USB и без ADC вполне можно обойтись.
По факту я опять оказался прав когда предположил, что речь идет об инженерных сэмплах, а вы опять ошиблись, когда решили, что скорее всего проблемы с производством )
Следующая проблема, что официальный стандарт C++ не фиксирует ABI
да в общем то это не проблема -- это достаточно здравый аспект, поскольку это стандарт языка программирования, а не функциональности аппаратуры с ПО...
И если для C тут всё довольно просто, то на C++ открывается весь масштаб ограничений динамического связывания.
да в общем то снова мимо я считаю -- поскольку всегда можно в таких случаях делать смотрящие наружу сущности под extern "C" -- никто тебя не ограничивает -- а динамического связывания на тех архитектурах которые ты упомянул скорее всего вообще нет, либо оно не рекомендовано к применению -- из чего следует истинный вывод, что никакой проблемы в общем то и нет -- просто надуманная проблема, не имеющая связи с реальностью.
Вы прикалыветесь? Для того, чтобы не использовать C++ ABI, Вы предлагаете использовать C ABI, отказавшись от объектов вообще, включая Ваш же std::array?
Для того, чтобы не использовать C++ ABI, Вы предлагаете использовать C ABI, отказавшись от объектов вообще, включая Ваш же std::array?
-- ну тут никаких грустей -- если надо универсализм для совместимости с другими возможными утилитами (либами) -- если делаешь либу для чего то, а не для C++... Тут я соглашусь что Си вообще надо ото всюду выпилить уже лет как 20 -- но увы люди адептичны (самый для меня напрашивающийся пример это Линус Торвальдс). Все бы заменить на C++'овые линковые вариации... Но для реалий, если надо предоставлять куда то доступ по динамической линковке -- это extern "C"...
Добавлено after 4 minutes 46 seconds: я же больше хотел выразить идею, что ты (ПростоНуб) неправильно вообще концептуально идею выражаешь -- у тебя концепция сама неверная -- из чего выходят все другие твои неправильные выводы. Нет никакой связи между С++ и ABI с точки зрения программирования -- это задача операционных систем (их аналогов) и компиляторов, а не пользователей в лице разработчиков программ (прошивок). Мы же исключительно ведем изначальную беседу про программирование на С++, а не как устроена конкретная "железка".
Добавлено after 4 minutes 31 second: и там еще один момент -- что прям большой по числу элементов std::array не всегда можно прям и передать (ограничения архитектуры по размеру данных передаваемых в функцию) -- тоесть имеет смысл делать такое для какого то привычно-определенного небольшого количества -- тупо вместо отдельных однотипных аргументов (что бы заагрегировать данные) -- при этом получается более гибкий вариант для использования (в частности для алгоритмов, циклов и подобного).
Нет никакой связи между С++ и ABI с точки зрения программирования
Так как я уже на примерах показал, что в C++ особенности его ABI просто необходимо учитывать при написании кода, Ваш выпад меня поражает. И даже если Вы откажетесь от использования C++ ABI в пользу C ABI, то вернемся к тому же, с чего начали. Массив будет передаваться указателем.
Так как я уже на примерах показал, что в C++ особенности его ABI просто необходимо учитывать при написании кода, Ваш выпад меня поражает.
-- как можно учитывать то, чего нет в самом ЯЗЫКЕ ПРОГРАММИРОВАНИЯ ? такое могут учитывать люди которые кодируют ОС или компиляторы -- но не кодеры программ на ЯП...
И даже если Вы откажетесь от использования C++ ABI в пользу C ABI, то вернемся к тому же, с чего начали. Массив будет передаваться указателем.
-- я уже выше делал отметку, что ты вообще путаешь концептуально мягкое с тёплым -- по этому приходишь снова и снова к неверному выводу... -- массив какой? в Си нельзя передать "массив" как аргумент функции -- он будет только в виде синтаксической записи там (тоесть для "указывания намерений по использованию" -- поскольку там не понятно хочешь ли юзать как поинтер на какие то данные для использования или как поинтер для возврата...). В С++ можно передать std::array -- он не может быть простым поинтером -- он исключительно как местная память по месту использования может существовать -- в аргументе функции я выше указывал как он должен восприниматься всеми -- в том числе компилятором. Никаких отступлений от этого быть не может.
Если Вы предлагаете писать код, не зная "как устроена конкретная железка", для которой этот код пишется, остается только над этим посмеяться.
-- почему же? я пишу на С++, который прям явно и недвусмысленно предлагает набор гарантий, на которые можно полагаться -- никаких сторонних сведений не требуется. Тут у тебя снова же как я выше указывал неверные выводы поскольку у тебя сама изначальная концепция неверна в понимании и восприятии -- из чего все последующие выводы соответственно не имеют ничего общего с реальностью.
Добавлено after 1 minute 56 seconds: иными словами ты не там хочешь модернизировать поведение программы... -- если надо уточнить и направить тебя на истинный нормальный вариант где надо что править для такого -- можешь спросить -- я отвечу... хотя частично уже выше ответил.
как можно учитывать то, чего нет в самом ЯЗЫКЕ ПРОГРАММИРОВАНИЯ ?
А как можно не учитывать в языке программирования проблемные требования? Для чего тогда вообще программа, если она учитывает только то, что есть в языке, на котором пишется?
1. А как можно не учитывать в языке программирования проблемные требования? Для чего тогда вообще программа, если она учитывает только то, что есть в языке, на котором пишется?
2. А почитать по ссылкам сил не хватило? Или перевести dynamic linking не удалось?
3. Для примера, для МК, не изучив даташит, Вы не напишете ничего путного. Несмотря на то, что даташит к языку программирования вообще отношения не имеет.
1. Что за проблемные требования? А как программа может содержать нечто, что не содержится в ЯП? 2. Ссылки не открываются у меня... но я понял про что, и оно к теме именно программирования в том числе прошивок не имеет никакого отношения. 3. Конечно лучше изучить даташит, вот только чем он может тут помочь преминимо к нашему обсуждению? Снова путается тёплое с мягким -- поскольку ты предлагал реализовывать в коде какие то вариации на тематику ABI, что соответственно выходит за рамки (или по крайней мере должно выходить за рамки) программирования на каком то ЯП, поскольку относится к формированию согласия взаимодействия какой то системы -- о котором ЯП в принципе не должен знать (конкретно С++).
К примеру могу привести отсутствие какой либо нужды знать конкретные реализации той же самой линковки -- поскольку никаким образом не может привести к изменению в коде... Гарантии С++ тут ничего не нарушают и не ухудшают -- они именно исключительно относимые к ЯП, а не к тому какую логику ты хочешь написать. В том числе ты можешь написать систему с каким угодно ABI -- в числе прочего со своей конвенцией о вызовах -- но это будет иметь отношение соответственно только к логике работы твоей программы (в том случае к ОС) -- ЯП и его гарантии никаким образом не будут зааффекчены -- все что действовало в одной системе относительно стандарта ЯП будет действовать и для всех иных, на которых данный ЯП предоставлен...
Добавлено after 50 seconds: по этому уже в который раз обращаю внимание на то, что у тебя именно сам изначальный концепт неверный, из чего соответственно сочатся неверные последующие выводы.
Добавлено after 1 minute 50 seconds: ну и снова же стоит упомянуть -- что ты пытаешься перекинуть какие то необходимости на код, который не должен такое решать... -- тоесть пытаешься править не то, где надо -- можно просто спросить, где надо что смотреть и улучшать -- я подскажу.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 6
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения