esaulenka 0 Posted October 29, 2018 · Report post Господа, а скажите мне, насколько необходима критическая секция INLINE tick_count_t get_tick_count() { TCritSect cs; return Kernel.SysTickCount; } Я помню о существовании порта на AVR (кто-нибудь пользуется, интересно?..), но для широко распространённых 32-битников можно съэкономить кучку тактов, добавив дефайн наподобие scmRTOS_SYSTEM_TICKS_ATOMIC. Quote Ответить с цитированием Share this post Link to post Share on other sites
AHTOXA 0 Posted October 29, 2018 · Report post Кстати да. Несколько раз возникала такая мысль. Quote Ответить с цитированием Share this post Link to post Share on other sites
dxp 0 Posted October 30, 2018 · Report post А тики могут быть 64-разрядными. А сколько тактов тратится?.. :) Ну, а если серьёзно, надо написать issue, чтобы не забыть. А ещё лучше pull request. Quote Ответить с цитированием Share this post Link to post Share on other sites
Сергей Борщ 0 Posted October 30, 2018 · Report post Видел правку в репозитории. Вот не согласен я с ней. Дело в том, что анлогично можно не обкладывать критической секцией еще кучу мест, например TEventFlag::clear(); TEventFlag::is_signaled(). Я думаю, что нужно делать какой-то #define или constexpr размера атомарного доступа и обернуть критическую секцию в шаблон с обрабатываемой перемененой в качестве параметра (я пока не знаю, как это сделать). И чтобы если размер переменной в параметре шаблона меньше либо равен размеру атомарного доступа - то шаблон бы разворачивался в ничто, а если больше - в критическую секцию. Quote Ответить с цитированием Share this post Link to post Share on other sites
esaulenka 0 Posted October 30, 2018 · Report post 6 minutes ago, Сергей Борщ said: Видел правку в репозитории. Вот не согласен я с ней. Значит, не зря я начал это обсуждение :-) 7 minutes ago, Сергей Борщ said: Дело в том, что анлогично можно не обкладывать критической секцией еще кучу мест Угу. Мысль хорошая. TEventFlag, на мой взгляд, будет работать без критической секции вообще. Булевый флажок влезает в атомарные чтение/запись в любом случае. А вот для mutex'а, например, стоит придумать что-нибудь. Я не плюсплюс-гуру, но попробую... Quote Ответить с цитированием Share this post Link to post Share on other sites
dxp 0 Posted October 30, 2018 · Report post 31 минуту назад, Сергей Борщ сказал: И чтобы если размер переменной в параметре шаблока меньше либо равен размеру атомарного доступа - то шаблон бы разворачивался в ничто, а если больше - в критическую секцию. Да, вот тоже думал о чём-то вроде этого (просто макрос в лоб - грубо и громоздко), наподобие как в шаблонах traits. Но образования в этой теме не хватает, давно уже плюсизмом не занимаюсь. Quote Ответить с цитированием Share this post Link to post Share on other sites
AHTOXA 0 Posted October 30, 2018 · Report post 2 часа назад, Сергей Борщ сказал: Видел правку в репозитории. Вот не согласен я с ней. Эх. А я уже тогось, принял эту правку. Не подумал сюда заглянуть сначала. Ладно, пусть пока так будет, а если (когда) появится более универсальное решение, то заменим. 2 часа назад, Сергей Борщ сказал: Я думаю, что нужно делать какой-то #define или constexpr размера атомарного доступа и обернуть критическую секцию в шаблон с обрабатываемой перемененой в качестве параметра (я пока не знаю, как это сделать). И чтобы если размер переменной в параметре шаблона меньше либо равен размеру атомарного доступа - то шаблон бы разворачивался в ничто, а если больше - в критическую секцию. Есть же для этого стандартное решение в плюсах -- std::atomic. Но можно и что-то своё наколбасить подобное, если не все компиляторы могут c++11. Quote Ответить с цитированием Share this post Link to post Share on other sites
dxp 0 Posted October 31, 2018 · Report post 11 часов назад, AHTOXA сказал: std::atomic А оно разве не для плюсовых же тредов? Нам-то как это может помочь? Quote Ответить с цитированием Share this post Link to post Share on other sites
AHTOXA 0 Posted October 31, 2018 · Report post Треды - они и в Африке треды. Конкурентные потоки исполнения. Атомики как раз для этого придуманы. Но надо смотреть, как они конкретно реализованы. Посмотрел сейчас, во что выливается работа с std::atomic<uint32_t> на кортексах. Чтение: барьер, чтение, барьер. Запись: барьер, запись, барьер. А вот с инкрементом уже посложнее: 80029c6: f3bf 8f5b dmb ish 80029ca: e853 2f00 ldrex r2, [r3] 80029ce: 3201 adds r2, #1 80029d0: e843 2100 strex r1, r2, [r3] 80029d4: 2900 cmp r1, #0 80029d6: d1f8 bne.n 80029ca <test1()+0x26> 80029d8: f3bf 8f5b dmb ish Да, думаю, что для тиков это будет перебор. Quote Ответить с цитированием Share this post Link to post Share on other sites
dxp 0 Posted October 31, 2018 · Report post Что-то это какой-то другой тип атомарности. Барьеры - это борьба с проблемами, возникающими из-за конвейеров, а у нас-то критическая секция - это предотвращение ошибок из-за того, что объект сам по себе требует нескольких операций обращения со стороны аппаратуры. Представь, что у тебя объект на кортексе твоём имеет размер больше 32 бит, это потребует как минимум два обращения, и если между ними произойдёт прерывание и переключение в другой процесс, где опять доступ к этому же объекту, то как тут помогут барьеры? Quote Ответить с цитированием Share this post Link to post Share on other sites
AHTOXA 0 Posted October 31, 2018 · Report post Мне было интересно, какие накладные добавятся для типа, который по идее атомарен. Вижу - барьеры (может, у нас они и не нужны, но в компиляторе так заложено, для чипов с кешами и несколькими ядрами). Вижу - аккуратный инкремент с использованием функций исключительного доступа (нам тоже не всегда нужен, например, для tick_count - не нужен). Получается, что именно в плане оптимизации (начальный посыл этой темы) - std::atomic не очень подходит. Попробовал atomic<uint64_t> - не скомпилировалось (undefined reference to `__atomic_load_8'). Наверное у меня компилятор старый. Так что я не смог увидеть, во что выливается atomic в случае, когда для доступа к переменной нужно несколько операций. Quote Ответить с цитированием Share this post Link to post Share on other sites
jcxz 0 Posted October 31, 2018 · Report post 44 минуты назад, AHTOXA сказал: Попробовал atomic<uint64_t> - не скомпилировалось (undefined reference to `__atomic_load_8'). Наверное у меня компилятор старый. Так что я не смог увидеть, во что выливается atomic в случае, когда для доступа к переменной нужно несколько операций. А куда делись инструкции LDRD/STRD/LDM/STM из кортексов? Quote Ответить с цитированием Share this post Link to post Share on other sites
esaulenka 0 Posted October 31, 2018 · Report post Попробовал. Своих умений не хватило, к сожалению. Спасибо добрым людям из телеграмма pro.cxx Получилось некоторое нагромождение шаблонов: https://godbolt.org/z/yJiCQS Слушаю предложения и замечания (а заодно и тесты на не-gcc. У меня под рукой только древний кейл). Quote Ответить с цитированием Share this post Link to post Share on other sites
AHTOXA 0 Posted October 31, 2018 · Report post Если используется #include <type_traits> и auto, то это уже c++11. А если можно c++11, то незачем городить эти шаблоны вручную, там есть std::conditional. Но вообще, лучше бы, наверное, наоборот, вычистить c++11. Потому что, например, AVR-GCC на godbolt не понимает "-std=c++11". Что там сейчас используется от с++11? std::is_arithmetic и std::is_enum. Думаю, можно обойтись без. Ещё такой момент. max_atomic_size = 4 - это же для ARM-ов. Для AVR-ок будет иначе. Надо как-то унифицировать. Или наоборот, вынести новый класс критической секции в порты, чтобы под каждую архитектуру был свой. ЗЫ. Я, если честно, не представляю, как сейчас всё это тестировать. С IAR-ом большой напряг, AVR-овец и STM8-овец уже давным-давно не появлялся... MSP-GCC у меня вроде есть, не знаю, насколько актуальный. Quote Ответить с цитированием Share this post Link to post Share on other sites
dxp 0 Posted November 1, 2018 · Report post И ещё не очень понятно, как это по месту использовать, чтобы автоматом оно понимало что с чем сравнивать. Ведь не догадается же компилятор о том, обращения к каким по размеру объектам производится. Это надо будет, получается, как-то указывать руками в каждом случае, что ли. А это уже громоздко и чревато ошибками, имхо. Quote Ответить с цитированием Share this post Link to post Share on other sites