Перейти к содержанию
    

Господа, а скажите мне, насколько необходима критическая секция

    INLINE tick_count_t get_tick_count() { TCritSect cs; return Kernel.SysTickCount; }

Я помню о существовании порта на AVR (кто-нибудь пользуется, интересно?..), но для широко распространённых 32-битников можно съэкономить кучку тактов, добавив дефайн наподобие scmRTOS_SYSTEM_TICKS_ATOMIC.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А тики могут быть 64-разрядными. А сколько тактов тратится?.. :) Ну, а если серьёзно, надо написать issue, чтобы не забыть. А ещё лучше pull request.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Видел правку в репозитории. Вот не согласен я с ней. Дело в том, что анлогично можно не обкладывать критической секцией еще кучу мест, например TEventFlag::clear(); TEventFlag::is_signaled(). Я думаю, что нужно делать какой-то #define или constexpr размера атомарного доступа и обернуть критическую секцию в шаблон с обрабатываемой перемененой в качестве параметра (я пока не знаю, как это сделать). И чтобы если размер переменной в параметре шаблона меньше либо равен размеру атомарного доступа - то шаблон бы разворачивался в ничто, а если больше - в критическую секцию. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 minutes ago, Сергей Борщ said:

Видел правку в репозитории. Вот не согласен я с ней.

Значит, не зря я начал это обсуждение :-)

 

7 minutes ago, Сергей Борщ said:

Дело в том, что анлогично можно не обкладывать критической секцией еще кучу мест

Угу. Мысль хорошая.

TEventFlag, на мой взгляд, будет работать без критической секции вообще. Булевый флажок влезает в атомарные чтение/запись в любом случае.

А вот для mutex'а, например, стоит придумать что-нибудь. Я не плюсплюс-гуру, но попробую...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

31 минуту назад, Сергей Борщ сказал:

 И чтобы если размер переменной в параметре шаблока меньше либо равен размеру атомарного доступа - то шаблон бы разворачивался в ничто, а если больше - в критическую секцию. 

Да, вот тоже думал о чём-то вроде этого (просто макрос в лоб - грубо и громоздко), наподобие как в шаблонах traits. Но образования в этой теме не хватает, давно уже плюсизмом не занимаюсь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, Сергей Борщ сказал:

Видел правку в репозитории. Вот не согласен я с ней.

Эх. А я уже тогось, принял эту правку. Не подумал сюда заглянуть сначала. Ладно, пусть пока так будет, а если (когда) появится более универсальное решение, то заменим.

 

2 часа назад, Сергей Борщ сказал:

Я думаю, что нужно делать какой-то #define или constexpr размера атомарного доступа и обернуть критическую секцию в шаблон с обрабатываемой перемененой в качестве параметра (я пока не знаю, как это сделать). И чтобы если размер переменной в параметре шаблона меньше либо равен размеру атомарного доступа - то шаблон бы разворачивался в ничто, а если больше - в критическую секцию. 

Есть же для этого стандартное решение в плюсах -- std::atomic. Но можно и что-то своё наколбасить подобное, если не все компиляторы могут c++11.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

11 часов назад, AHTOXA сказал:

std::atomic

А оно разве не для плюсовых же тредов? Нам-то как это может помочь?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Треды - они и в Африке треды. Конкурентные потоки исполнения. Атомики как раз для этого придуманы. Но надо смотреть, как они конкретно реализованы.

Посмотрел сейчас, во что выливается работа с 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

Да, думаю, что для тиков это будет перебор.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что-то это какой-то другой тип атомарности. Барьеры - это борьба с проблемами, возникающими из-за конвейеров, а у нас-то критическая секция - это предотвращение ошибок из-за того, что объект сам по себе требует нескольких операций обращения со стороны аппаратуры. Представь, что у тебя объект на кортексе твоём имеет размер больше 32 бит, это потребует как минимум два обращения, и если между ними произойдёт прерывание и переключение в другой процесс, где опять доступ к этому же объекту, то как тут помогут барьеры?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мне было интересно, какие накладные добавятся для типа, который по идее атомарен. Вижу - барьеры (может, у нас они и не нужны, но в компиляторе так заложено, для чипов с кешами и несколькими ядрами). Вижу - аккуратный инкремент с использованием функций исключительного доступа (нам тоже не всегда нужен, например, для tick_count - не нужен). Получается, что именно в плане оптимизации (начальный посыл этой темы) - std::atomic не очень подходит.

Попробовал atomic<uint64_t> - не скомпилировалось (undefined reference to `__atomic_load_8'). Наверное у меня компилятор старый. Так что я не смог увидеть, во что выливается atomic  в случае, когда для доступа к переменной нужно несколько операций.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

44 минуты назад, AHTOXA сказал:

Попробовал atomic<uint64_t> - не скомпилировалось (undefined reference to `__atomic_load_8'). Наверное у меня компилятор старый. Так что я не смог увидеть, во что выливается atomic  в случае, когда для доступа к переменной нужно несколько операций.

А куда делись инструкции LDRD/STRD/LDM/STM из кортексов?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Попробовал. Своих умений не хватило, к сожалению. Спасибо добрым людям из телеграмма pro.cxx

Получилось некоторое нагромождение шаблонов: https://godbolt.org/z/yJiCQS

Слушаю предложения и замечания (а заодно и тесты на не-gcc. У меня под рукой только древний кейл).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если используется #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 у меня вроде есть, не знаю, насколько актуальный.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И ещё не очень понятно, как это по месту использовать, чтобы автоматом оно понимало что с чем сравнивать. Ведь не догадается же компилятор о том, обращения к каким по размеру объектам производится. Это надо будет, получается, как-то указывать руками в каждом случае, что ли. А это уже громоздко и чревато ошибками, имхо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...