Подготовил релиз второй версии нодграфов. Заинтересованные могут посмотреть на изменения в API и дать ценный фидбэк заранее
👍1
https://crates.io/crates/egui-snarl
Версия 0.2
Рефакторинг, API без RefCell и с типизированными идентификаторами нод.
Новые опциональные области для контента в нодах - тело между пинами и футер в самом низу.
Опциональный попап при наведении курсора на ноду.
Фикс скейлинга, теперь почти нет дребезжания размера нод.
И другие мелкие изменения.
Сделал все крупные запланированные ломающие изменения.
Дальше можно и без них все планы реализовать.
Версия 0.2
Рефакторинг, API без RefCell и с типизированными идентификаторами нод.
Новые опциональные области для контента в нодах - тело между пинами и футер в самом низу.
Опциональный попап при наведении курсора на ноду.
Фикс скейлинга, теперь почти нет дребезжания размера нод.
И другие мелкие изменения.
Сделал все крупные запланированные ломающие изменения.
Дальше можно и без них все планы реализовать.
crates.io
crates.io: Rust Package Registry
🔥7
This media is not supported in your browser
VIEW IN TELEGRAM
Пофиксил все артефакты, которые проявились в демке при использовании разных стилей.
Для этого подключил https://github.com/zakarumych/egui-probe и задерайвил
Для этого подключил https://github.com/zakarumych/egui-probe и задерайвил
EguiProbe
для SnarlStyle
и добавил виджет в демку. Теперь все стили графа можно редактировать прямо вот так.🔥3👍1👌1
У меня выработалась хорошая привычка сразу документировать safety требования и обоснования вокруг
Но есть один случай, когда приходится писать
И ничего тут не поделаешь. Можно сколько угодно протаскивать
Что ж это за жестокая ирония и когда крабам приходится идти на трюки и соглашаться на "безопасно на практике" вместо полной гарантии безопасности?
Первый написавший правильный ответ в комментарии к посту заслужит почет и уважение.
unsafe
кода.unsafe fn
- сразу пишу как не получить с ней UB.unsafe {}
- почему тут не будет UB. Для этого есть clippy lint clippy::undocumented_unsafe_blocks
. Также всегда советую делать #![forbid(unsafe_op_in_unsafe_fn)]
если нету #![forbid(unsafe)]
.Но есть один случай, когда приходится писать
// SAFETY: Practically safe, but generally nope.
unsafe { ... }
И ничего тут не поделаешь. Можно сколько угодно протаскивать
unsafe
наверх, хоть до main
, но там придется сделать вот такой unsafe
блок.Что ж это за жестокая ирония и когда крабам приходится идти на трюки и соглашаться на "безопасно на практике" вместо полной гарантии безопасности?
Первый написавший правильный ответ в комментарии к посту заслужит почет и уважение.
👍9🤔1
Давненько ничего не писал. Ни тут не писал, ни на Rust.
Хватит это терпеть, как говориться.
Сегодня добавил еще одну структуру данных в свой арсенал.
Сей арсенал запакован в crate
Который я и опубликовал. https://docs.rs/amity/latest/amity/
Верхнеуровневая документация хромает, но стараюсь хотя бы типы и методы задокументировать как следует.
Что есть в этой библиотеке. От простого к сложному
1. `CacheAlign
False sharing происходит когда два потока одновременно обращаются к двум разным областям памяти, которые разделяют кэш-линию.
Один поток делает запись и инвалидирует всю кэш-линию, второй поток вынужден ее обновлять, хотя данные, которые нужны потоку вовсе не поменялись.
Предоставленные типы могут быть использованы для конструирования других конкурентных структур данных.
2. `TripleBuffer` - очень простой в использовании и эффективный single-producer single-consumer канал с емкостью очереди 1.
Особенно полезен, когда consumer читает значения и их можно переиспользовать в producer-е, экономя гига-циклы.
Например когда значения содержат ссылки на ресурсы или аллоцирую память.
К тому же producer знает, было ли значение прочитано consumer-ом или нет и обновить его соответствующе, что может дать не только бонус к производительности, но и вовсе сделать алгоритм невозможный с обычным каналом.
3. `BackOff` используется в различных алгоритмах ожидания, что бы делать сначала busy spin, переходить к более энергоэффективным thread yield и наконец остановке треда.
4. `RawSpin` - самая простая имплементация блокировки на основе busy spin. Использует BackOff. Совместим в lock_api.
5. `FlipBuffer` - кольцевой буфер с возможностью добавлять в значения параллельно и без блокировок. Но только пока вместимости хватает.
`FlipQueue` - надстройка над
Оба варианта могут быть использованы в fork-join сценариях, где fork-и могут эффективно добавлять значения в очередь, а забираются они после join или очень редко в fork-ах.
6. `park` - модуль с абстрактным thread parking. С
Блокирующие алгоритмы (кроме spin) могут использовать любую реализацию.
7. `PtrState
`AtomicPtrState` занимает 1
8. `CondVar` - классический conditional variable на основе AtomicPtrState. Все операции требуют не более одного CAS вы цикле. Может использовать любой thread parking из модуля выше.
Позволяет закодировать 8 бит состояния и обновлять, записывать, ожидать его.
И другие экспериментальные вещи.
У этого crate-а нет зависимостей кроме
Можно использовать с/без
Библиотеке явно не хватает серьезного тестирования, но как минимум некоторые тесты под miri она проходит.
Хватит это терпеть, как говориться.
Сегодня добавил еще одну структуру данных в свой арсенал.
Сей арсенал запакован в crate
amity
(англ. peaceful relations, as between nations; friendship).Который я и опубликовал. https://docs.rs/amity/latest/amity/
Верхнеуровневая документация хромает, но стараюсь хотя бы типы и методы задокументировать как следует.
Что есть в этой библиотеке. От простого к сложному
1. `CacheAlign
и
CachePadded` позволяют выравнивать данные по краям кэш-линий, избегая ситуации false sharing.False sharing происходит когда два потока одновременно обращаются к двум разным областям памяти, которые разделяют кэш-линию.
Один поток делает запись и инвалидирует всю кэш-линию, второй поток вынужден ее обновлять, хотя данные, которые нужны потоку вовсе не поменялись.
Предоставленные типы могут быть использованы для конструирования других конкурентных структур данных.
2. `TripleBuffer` - очень простой в использовании и эффективный single-producer single-consumer канал с емкостью очереди 1.
Особенно полезен, когда consumer читает значения и их можно переиспользовать в producer-е, экономя гига-циклы.
Например когда значения содержат ссылки на ресурсы или аллоцирую память.
К тому же producer знает, было ли значение прочитано consumer-ом или нет и обновить его соответствующе, что может дать не только бонус к производительности, но и вовсе сделать алгоритм невозможный с обычным каналом.
3. `BackOff` используется в различных алгоритмах ожидания, что бы делать сначала busy spin, переходить к более энергоэффективным thread yield и наконец остановке треда.
4. `RawSpin` - самая простая имплементация блокировки на основе busy spin. Использует BackOff. Совместим в lock_api.
5. `FlipBuffer` - кольцевой буфер с возможностью добавлять в значения параллельно и без блокировок. Но только пока вместимости хватает.
`FlipQueue` - надстройка над
FlipBuffer
, которая добавляет значения под shared lock, пока хватает вместимости и делает unique lock при необходимости, а так же что бы забрать значения.Оба варианта могут быть использованы в fork-join сценариях, где fork-и могут эффективно добавлять значения в очередь, а забираются они после join или очень редко в fork-ах.
6. `park` - модуль с абстрактным thread parking. С
`std
` можно использовать Thread
и стандартный паркинг. Без std
остается thread yield. Но пользователь может использовать кастомную реализацию.Блокирующие алгоритмы (кроме spin) могут использовать любую реализацию.
7. `PtrState
и
AtomicPtrState` - комбинирует указатель и состояние в одном значении и позволяет атомарно читать и модифицировать. Неатомарная версия предоставлена для полноты.`AtomicPtrState` занимает 1
usize
и позволяет совершать те же операции что и AtomicUsize
или AtomicPtr
. Для состояния используются биты, которые гарантируются быть нулевыми в указателе в результате выравнивания. Адрес и состояние аккуратно разделяются и смешиваются, гарантируя сохранение provenance указателя.8. `CondVar` - классический conditional variable на основе AtomicPtrState. Все операции требуют не более одного CAS вы цикле. Может использовать любой thread parking из модуля выше.
Позволяет закодировать 8 бит состояния и обновлять, записывать, ожидать его.
И другие экспериментальные вещи.
У этого crate-а нет зависимостей кроме
lock_api
для реализации трейтов из него и объявления синонимов типов.Можно использовать с/без
std
и alloc
.Библиотеке явно не хватает серьезного тестирования, но как минимум некоторые тесты под miri она проходит.
docs.rs
amity - Rust
Amity crate.
👍10🔥4❤2
This media is not supported in your browser
VIEW IN TELEGRAM
Получился вот такой вот проводок.
Ваши мысли?
Ваши мысли?
👍7
This media is not supported in your browser
VIEW IN TELEGRAM
После небольшого отдыха я продолжил работать над движком.
Обновил зависимости и порефакторил.
После чего занялся той самой задачей, от которой выгорел в прошлый раз - gpu work graph.
И вот оно работает.
Обновил зависимости и порефакторил.
После чего занялся той самой задачей, от которой выгорел в прошлый раз - gpu work graph.
И вот оно работает.
🔥11👏2👍1
This media is not supported in your browser
VIEW IN TELEGRAM
Опять я отвлекаюсь от графики.
Недавно я сделал библиотеку
Но это редактирование конкретного типа. А что если типа нет?
Совсем без схемы делать ну такое.
Хоче рантаймовую опциональную схему и генерировать UI для неё.
Поэтому сегодня я сделал новую библиотеку.
Она предоставляет тип
А так же тип
Сам он при этом может редактироваться с помощью
А объединяя
Самое замечательное, что почти не пришлось писать UI кода в этот раз.
Всю тяжелую UI работу делает
На видео показан demo example.
Недавно я сделал библиотеку
egui-probe
для генерации UI редактирования значения любых типов с помощью EguiProbe
трейта, который можно задерайвить.Но это редактирование конкретного типа. А что если типа нет?
Совсем без схемы делать ну такое.
Хоче рантаймовую опциональную схему и генерировать UI для неё.
Поэтому сегодня я сделал новую библиотеку.
Она предоставляет тип
Value
который может принимать несколько классических вариантов данных.А так же тип
Desc
, который описыает схему.Сам он при этом может редактироваться с помощью
EguiProbe
.А объединяя
Value
и Desc
можно получить ValueProbe
, который может быть использован для редактирования значения согласно схеме.Самое замечательное, что почти не пришлось писать UI кода в этот раз.
Всю тяжелую UI работу делает
egui-probe
На видео показан demo example.
🔥7
This media is not supported in your browser
VIEW IN TELEGRAM
И конечно можно указать
Desc
на любом уровне, где его нет.This media is not supported in your browser
VIEW IN TELEGRAM
"Почему бы не добавить конфигурацию рендерджобам прямо в граф?" подумал я пару дней назад
🥰4
This media is not supported in your browser
VIEW IN TELEGRAM
Пора бы уже соединять чуть более сложный граф, чем draw -> present.
Конечно же нашлось чуть более чем ноль багов.
Конечно же нашлось чуть более чем ноль багов.
👍2
This media is not supported in your browser
VIEW IN TELEGRAM
Добавил хуки к рендерграфу и научил эдитор показывать каждый выход если это Image2D.
👍1
Ну все, я официально умею в нейронки теперь.
Закончил писать обучение и предсказание на HLSL.
Оно еще и быстрее местами работает, чем из фреймворка.
Добавил бы в движок, но в движке до сих пор нету 3д.
Видимо пора :)
Закончил писать обучение и предсказание на HLSL.
Оно еще и быстрее местами работает, чем из фреймворка.
Добавил бы в движок, но в движке до сих пор нету 3д.
Видимо пора :)
👍6🐳5
Начал тут описывать архитектуру движка какая выходит.
https://github.com/zakarumych/nothing/blob/wip/README.md
https://github.com/zakarumych/nothing/blob/wip/README.md
GitHub
arcana/README.md at wip · zakarumych/arcana
There's nothing here. Contribute to zakarumych/arcana development by creating an account on GitHub.
👍4
Возможно многие как и я ждут эту фичу.
Она должны быть в следующием релизе на stable.
Она позволяет исправить следующий код что бы тот компилился.
Что же это за фича?
Она должны быть в следующием релизе на stable.
Она позволяет исправить следующий код что бы тот компилился.
fn get_iter<'a, T>(q: Option<&'a VecDeque<T>>) -> std::collections::vec_deque::Iter<'a, T> {
q.unwrap_or(&VecDeque::new()).iter()
}
Что же это за фича?
🤔4
Правильный ответ - inline const
https://doc.rust-lang.org/unstable-book/language-features/inline-const.html
Фикс
Q: Почему это работает?
A: Создаваемая ссылка становится
Q: Почему нужен блок?
A: Потому что иначе rustc берет ссылку уже в runtime контексте и она на temporary значение.
https://doc.rust-lang.org/unstable-book/language-features/inline-const.html
Фикс
fn get_iter<'a, T>(q: Option<&'a VecDeque<T>>) -> std::collections::vec_deque::Iter<'a, T> {
q.unwrap_or(const { &VecDeque::new() }).iter()
}
Q: Почему это работает?
A: Создаваемая ссылка становится
&'static
.Q: Почему нужен блок?
A: Потому что иначе rustc берет ссылку уже в runtime контексте и она на temporary значение.
🔥9👍1