[ Главная · Новые сообщения · Участники · Правила форума · Поиск · RSS ]
Пытаюсь замутить свой симулятор.
V9Дата: Пятница, 07.06.2024, 13:26 | Сообщение # 181
Поездной диспетчер
Группа: Пользователи
Сообщений: 441
Награды: 9
Репутация: 0
Статус: Offline
Цитата V9 ()
Есть у меня психологическая проблема. Я сам себе ставлю некие задачи повышенной сложности которые сам же потом не могу решить. Из-за чего общий прогресс замедляется или стоит на месте. Надеюсь, я смогу это побороть в себе.


Встрял на проблеме "параллельной работы двух потоков - Модели и Графики - и передачи данных между ними без задержек".

upd. Практически сразу нашлось правильное решение. Я на этой задаче месяц сидел, если без шуток. Поставил сам себе ограничения и не мог решить задачу в этих ограничениях. Но решил почти сразу, как выложил жалобу на форум.

Добавлено (10.06.2024, 12:51)
---------------------------------------------
В негативном ахрене от Java.

Суть. Обработка(программа) в DSim идет в два потока:

1. Поток №1 постоянно читает данные из GID.txt, разбирает их и должен отправить в поток №2. сигнализирует потоку №2 о поступлении новых данных.
2. Поток №2 занят отрисовкой графики на экране. Он вызывается (косвенно) из потока №1, а так же из операционки, если надо обновить окно (скажем, была другая прога над моим окном, убралась,надо отрисовать наше окно) или же как следствие действий пользователя. Скажем, пользователь изменил размеры, подвигал по окну мышкой, нажал клавиши и т.п.

По идее, ни поток №1, ни поток №2 никогда не должны тормозиться "обо что-то". Первый - потому что в будущем это должна быть Модель Мира, где будут ехать поезда и она должна в режиме реального времи все обсчитывать. Второй - потому что будет выглядеть как "тормозной интерфейс": пользователь максимизировал окно, прога задумалась, зависла, потом "раздуплилась".

Поэтому я ставил сам себе задачу написать передачу данных "без блокировок".
1. не должны использоваться мьютексы (mutex) - https://ru.wikipedia.org/wiki/%D0%9C%D1%8C%D1%8E%D1%82%D0%B5%D0%BA%D1%81
2. не должны использоваться volatile переменные, которые вызывают "атомарные операции" - https://ru.wikipedia.org/wiki/%D0%90%D1%82%D0%BE%D0%BC%D0%B0%D1%80%D0%BD%D0%B0%D1%8F_%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D1%8F
3. Какой бы большой пакет данных не пришел, он должен быть передан "за один цикл".
4. Прога должна минимизировать "удаление устаревших аднных", данные должны правиться, а не удаляться. Это означает, что требуется еще и передача "использованных данных" обратно из потока №2 в поток №1 под будущие данные из GID.txt.

Задача была очень сложной и интересной, я перебрал что-то около  100 вариантов прежде чем смог сделать. И....

Оффтоп. В современных компах много процессоров на одном ядре. У каждого процессора есть своя кэш-память https://ru.wikipedia.org/wiki/%D0%9A%D1%8D%D1%88_%D0%BF%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81%D0%BE%D1%80%D0%B0

Если процессор поменял значение ячейки памяти, это значение остется только в кэше этого процессора. Но другой процессор может тоже захотеть "ознакомиться" с этой ячейкой. И вот чтобы другой процессор не увидел "старое значение" ячейки, существует специальный протокол MESI - https://habr.com/ru/articles/183834/

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

"Переменные" в Java - это отсылки на ячейки оперативной памяти, которые, при работе, тоже будут сидеть в кэш-памяти. То есть, я рассчитываю, что записав некоторое значение в память с потока №1, через несколько пикосекунд я смогу ознакомиться со значением в другом потоке.  

Конец оффтопа.

Моя задача так написать алгоритм, чтобы при любой модификации не получилось так, что одна и та же ячейка пишется одновременно из двух потоков. Он хорошо отработал на "старой джаве", которая тут лежит и которую я рекомендую качать. Но у пользователя может быть новая джава. Поэтому я проверил алгоритм на новой джаве, заодно проверив "однозначность алгоритма" т.е. последовательность передачи-приема.

И врезался в ошибку... Алгоритм иногда(!) работал, иногда(!) нет. Ошибка была только на поздних релизах. Начал разбираться...

И в шоке выяснил, что в Java есть "оптимизатор": если "оптимизатор", условно, 1000 раз прочел ячейку и там наблюдал одно и то же значение, он делал "предположение", что в этой ячейке ВСЕГДА будет храниться одно и то же значение. И перекомпилировал код так, чтобы в программу всегда передавалось одно и то же "считанное" значение, без обращения к памяти.

То есть, я запускаю два потока.
1. Если "генератор" запускается раньше, чем "потребитель", то оптимизатор "потребителя" видит, что значения в ячейке постояно меняются "генератором": "генератор" запустился раньше и начал "срать" данными. Оптимизатор ничего не оптимизирует, продолжает читать из памяти.
2. Если "потребитель" запустился раньше "генератора", то "потребитель", условно, 1000 раз "крутанется", увидит, что 1000 раз там "ничего нет", запустится "оптимизатор" и отныне и до конца работы проги я буду получать "ничего нет!". "Потребитель", после отработки "оптимизатора" уже ничего не будет читать из памяти, просто будет "крутиться" в пустом цикле и ничего не будет делать. Только занимать процессор и греть воздух.

Добавлено (10.06.2024, 16:12)
---------------------------------------------
Что же предлагает джава,чтобы не нарваться на "оптимизатор"? По факту - "для передачи данных между  потоками используйте переменные типа volatile!" 

Volatile-переменные - дико медленные. При их использовании процессор блокирует шину передачи данных командой LOCK для остальных процессоров, а сведения отправляются напрямую из процессора в оперативную память. Все остальные процессоры  в этот момент сосут чупа-чупс стоят, если только не используют сведения из своей кэш-памяти. Команда LOCK используется для того, чтобы безопасно эксклюзивно обновить некую ячейку памяти. Но у меня специально было спроектировано так, чтобы этого не требовалось!

Сообщение отредактировал
V9 - Пятница, 07.06.2024, 21:19
 
V9Дата: Вторник, 25.06.2024, 09:05 | Сообщение # 182
Поездной диспетчер
Группа: Пользователи
Сообщений: 441
Награды: 9
Репутация: 0
Статус: Offline
Вернулся к разработке. Выяснилось, что я не знал, что такое поведение характерно для более высоких версий Java, где они, да, могут прятать переменные памяти в регистры. Но это потому, что для разрабов Java, в Java 9 ввели класс с методами VarHandle.setOpaque() и VarHandle.getOpaque(), которые может использовать программист чтобы приказать компилятору - "Так, Java! Вот конкретно вот тут фигней не страдаем, а пишем/читаем строго в(из) память(-ти)!
 
olegpersh999Дата: Вторник, 25.06.2024, 09:21 | Сообщение # 183
Начальник станции
Группа: Пользователи
Сообщений: 159
Награды: 3
Репутация: 0
Статус: Online
V9, надеюсь всё получится у тебя!
 
V9Дата: Вторник, 25.06.2024, 12:50 | Сообщение # 184
Поездной диспетчер
Группа: Пользователи
Сообщений: 441
Награды: 9
Репутация: 0
Статус: Offline
Ё! Первый поезд показался! V.0.0.6.13/

 Это с поездной ситуации Сургута, отправился 380й поезд.


Пока что там делается отбор только по Сургуту и только по поездам отправления. Нечетные на юг не показались потому что GID.txt  у меня был обрезанный.
ps. Релиз прикладывать? Он почти не работает и в разработке.
Прикрепления: 1457461.png (1.4 Kb) · 3151980.png (4.9 Kb)
 
V9Дата: Вторник, 25.06.2024, 13:25 | Сообщение # 185
Поездной диспетчер
Группа: Пользователи
Сообщений: 441
Награды: 9
Репутация: 0
Статус: Offline


Картинка релиза DSim с одной из моих реальных игр. Должно было отрисовываться и вниз, но до этого еще надо дойти =)
Прикрепления: 4538573.png (15.2 Kb)
 
V9Дата: Вторник, 25.06.2024, 13:50 | Сообщение # 186
Поездной диспетчер
Группа: Пользователи
Сообщений: 441
Награды: 9
Репутация: 0
Статус: Offline

V.0.0.6.14. Отрисовались все поезда по Сургуту.  В данный момент отрисоывается один час, последний оперативный. Убрал одну ошибку, когда обработка падала на "+" и "-" поезда (формируемые и расформируемые). Пока что не тестировалось динамическое взаимодействие с pult.exe в процессе игры. Релиз прикладываю. Запускать Startup.bat.
upd. v.0.0.6.15 Hotfix. аварийный вылет когда запускалась параллельная работа с Pult.exe. Исправлено. Теперь работает.
Прикрепления: 5977783.png (1.6 Kb) · dsim_0_0_6_15.zip (24.3 Kb)


Сообщение отредактировал
V9 - Вторник, 25.06.2024, 14:46
 
olegpersh999Дата: Среда, 26.06.2024, 10:16 | Сообщение # 187
Начальник станции
Группа: Пользователи
Сообщений: 159
Награды: 3
Репутация: 0
Статус: Online
Что-то не рисует или я что-то не так делаю?
Прикрепления: 2315650.jpg (143.6 Kb)
 
V9Дата: Среда, 26.06.2024, 13:41 | Сообщение # 188
Поездной диспетчер
Группа: Пользователи
Сообщений: 441
Награды: 9
Репутация: 0
Статус: Offline
Сорри! Не сказал. Это не релиз в смысле "Релиза" как "готовый продукт", это некая жуткая пре-пре-альфа в самой начальной разработке. Не удержался, выложил. "Зачем?" - честно сказать, сам не понял.
 
V9Дата: Среда, 26.06.2024, 16:07 | Сообщение # 189
Поездной диспетчер
Группа: Пользователи
Сообщений: 441
Награды: 9
Репутация: 0
Статус: Offline
Pre-alpha релиз 0.0.6.16



За часик работы сделал отрисовку всех станций пульта. Пока поезда не соединяются по линиям движения, нет маркировок и т.п. Это все будет решаться. Тут нет Ингу-ягуна и Покачей, как и нет Черного Мыса и нет Сургут-Порта так как эти станции вообще не пишутся в GID.txt.
Рабочие комбинации клавиш:
1. Ctrl-влево и Ctrl-вправо меняют цветовую схему.
2. Ctrl-i инвертирует график, четные начинают ехать вниз. Это случай olegpersh999.

upd. Подобрал размеры, че-то даже подсовпало.
Прикрепления: 6110390.png (7.6 Kb) · dsim_0_0_6_16.zip (24.3 Kb) · 5924358.png (12.1 Kb)


Сообщение отредактировал
V9 - Среда, 26.06.2024, 18:51
 
olegpersh999Дата: Четверг, 27.06.2024, 09:28 | Сообщение # 190
Начальник станции
Группа: Пользователи
Сообщений: 159
Награды: 3
Репутация: 0
Статус: Online
У меня что-то совсем ничего не рисует
Прикрепления: 0052115.jpg (36.6 Kb)
 
V9Дата: Четверг, 27.06.2024, 10:46 | Сообщение # 191
Поездной диспетчер
Группа: Пользователи
Сообщений: 441
Награды: 9
Репутация: 0
Статус: Offline
gid.txt приложите, плиз, из каталога territory\1
 
olegpersh999Дата: Четверг, 27.06.2024, 13:04 | Сообщение # 192
Начальник станции
Группа: Пользователи
Сообщений: 159
Награды: 3
Репутация: 0
Статус: Online
Прикладываю
 
olegpersh999Дата: Четверг, 27.06.2024, 13:04 | Сообщение # 193
Начальник станции
Группа: Пользователи
Сообщений: 159
Награды: 3
Репутация: 0
Статус: Online
...
Прикрепления: GID.rar (12.6 Kb)
 
V9Дата: Четверг, 27.06.2024, 17:28 | Сообщение # 194
Поездной диспетчер
Группа: Пользователи
Сообщений: 441
Награды: 9
Репутация: 0
Статус: Offline
Цитата olegpersh999 ()
Прикладываю


Хм, у меня вот так ваш гид отрисовался. Возможный некий глюк при совместной работе с pult.exe.
ps. Такая возможность может быть если pult.exe сделал "рваную" строку, записав полстроки. DSim глюканет в такой ситуации. Надо будет обдумать.
Прикрепления: 0827223.png (15.6 Kb)
 
V9Дата: Пятница, 28.06.2024, 04:55 | Сообщение # 195
Поездной диспетчер
Группа: Пользователи
Сообщений: 441
Награды: 9
Репутация: 0
Статус: Offline

Уже похоже на правду. Сделана отрисовка "между-станциями". Одна линия на чертеже выглядит багом(ошибкой), но это так разные поезда наложились на участке УЯ-Чу
Прикрепления: 1390926.png (6.8 Kb) · dsim_0_0_6_17.zip (24.5 Kb)


Сообщение отредактировал
V9 - Пятница, 28.06.2024, 06:27
 
V9Дата: Пятница, 28.06.2024, 06:29 | Сообщение # 196
Поездной диспетчер
Группа: Пользователи
Сообщений: 441
Награды: 9
Репутация: 0
Статус: Offline
Ветка 0.0.6 заканчивается,  начинается ветка 0.0.7. В новой ветки планируется:
  • Отрисовка двух часов вместо одного, автоматический сдвиг картинки при переходе в новый час
  • Линии часовые, минутные
  • Отрисовка последней минуты отправления/прибытия.
 
V9Дата: Пятница, 28.06.2024, 12:43 | Сообщение # 197
Поездной диспетчер
Группа: Пользователи
Сообщений: 441
Награды: 9
Репутация: 0
Статус: Offline


Красота, правда?
Релиз 0.0.7.0. Клавиши управления:
Ctrl-i - инверсия по вертикали.
Ctrl-o - увеличить количество демонстрируемого времени на экране
Ctrl-p - уменьшить -------------------- // --------------------- // ------------------------

Ctrl+ стрелка влево (стрелка вправо) - сменить графику.
Прикрепления: 2824611.png (48.6 Kb) · dsim_0_0_7_0.zip (24.7 Kb)
 
V9Дата: Суббота, 29.06.2024, 20:24 | Сообщение # 198
Поездной диспетчер
Группа: Пользователи
Сообщений: 441
Награды: 9
Репутация: 0
Статус: Offline


Присутствуют косяки в цифрах. Прибытие накладывается на отправление или же транзит. Это будет исправляться, поэтому релиз не выложил.
Прикрепления: 5099937.png (8.8 Kb)


Сообщение отредактировал
V9 - Суббота, 29.06.2024, 21:07
 
V9Дата: Суббота, 29.06.2024, 22:38 | Сообщение # 199
Поездной диспетчер
Группа: Пользователи
Сообщений: 441
Награды: 9
Репутация: 0
Статус: Offline
Релиз пре-Альфа 0.0.7.3. Добавлена отрисовка минутных линий, добавлена возможность "отмотать" командой ctrl-o до 24 часов назад (до начала суток). Добавлена отрисовка "хвостовых" минутных цифр отправления/прибытия. Ошибка "наложения" цифр с предыдущей картинки исправлена.
"Минутные цифры" можно отключить комбинацией клавиш Ctrl-m (Ctrl-M)

Важно! Не тестировалось функционирование совместно с Pult.exe! Особенной глючным может быть "перелом" суток. 

Прикрепления: dsim_0_0_7_3.zip (25.2 Kb)
 
V9Дата: Воскресенье, 30.06.2024, 08:33 | Сообщение # 200
Поездной диспетчер
Группа: Пользователи
Сообщений: 441
Награды: 9
Репутация: 0
Статус: Offline
Прикрепления: 4749671.png (664.2 Kb)
 
Поиск: