Size: a a a

Язык программирования Julia / Julia programming language

2020 February 18

KT

Kirill Tsaregorodtsev in Язык программирования Julia / Julia programming language
а как понять, сложная ли проблема
источник

АО

Андрей Оськин in Язык программирования Julia / Julia programming language
😊) Если просто не решается, то значит сложная 😊))))
источник

АО

Андрей Оськин in Язык программирования Julia / Julia programming language
Не знаю :) Это чисто эмпирическая штука, разумеется.
источник

KT

Kirill Tsaregorodtsev in Язык программирования Julia / Julia programming language
Я вообще не согласен, в 10м веке все бы согласились, что очень сложно решать квадратные уравнения или что сложно изучать алгебраические многообразия и т.д.
источник

KT

Kirill Tsaregorodtsev in Язык программирования Julia / Julia programming language
а потом появились удобные представления, и задачи очень быстро решились
источник

АО

Андрей Оськин in Язык программирования Julia / Julia programming language
Да, но зато осознать как работают эти представления стало гораздо сложнее, чем понять, что такое квадратное уравнение. Просто фокус сместился со сложности решения задачи на сложность понимания формалистики.
источник

АО

Андрей Оськин in Язык программирования Julia / Julia programming language
В сумме мало что поменялось на самом деле. Но только в сумме.
источник

АО

Андрей Оськин in Язык программирования Julia / Julia programming language
Разумеется правило полушуточное и чересчур серьёзно к нему относиться нельзя.
источник

KT

Kirill Tsaregorodtsev in Язык программирования Julia / Julia programming language
Я просто диссер пишу потихоньку, и вопрос : а как это перекодировать, чтобы получилось просто решить -- очень насущный 😂
источник

АО

Андрей Оськин in Язык программирования Julia / Julia programming language
Ну вот, закон сохранения сложности в силе 😊 Будет простой способ решения решить задачу, но чтобы его понять - надо прочитать и понять сложный диссер 😊))
источник

S

Serg in Язык программирования Julia / Julia programming language
Андрей Оськин
Не знаю :) Это чисто эмпирическая штука, разумеется.
Красивое представление.. похоже на энтропийный постулат
источник

KT

Kirill Tsaregorodtsev in Язык программирования Julia / Julia programming language
Serg
Красивое представление.. похоже на энтропийный постулат
Ну да, или на алгоритмическую сложность по Колмогорову
источник

RC

Roman Chebotarev in Язык программирования Julia / Julia programming language
Андрей Оськин
У меня нет опыта в разработке сложных симуляций, но могу поделиться своими мыслями, если интересно.

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

Самая очевидная проблема: так как симуляция обычно вычисляется как x_{n+1} = f(x_n), то среда и агенты должны быть иммутабельными, то есть к концу вычисления нового шага у тебя в памяти будут две копии среды - от предыдущего шага и от нового. Если (условно) у тебя одно состояние занимает 10 Гб, то два состояния будут занимать 20 и меньше ты не сделаешь никак. Можно конечно пытаться как-то хранить распределённо, но это чистый кастом, вряд ли фреймворки из коробки позволят тебе это сделать за просто так.

Но это только одна сторона проблемы, менее тривиальный аспект заключается в том, что все промежуточные вычисления могут аллоцировать и это нужно ловить постоянно. Каждый аллоцированный байт нужно умножать на 10 млн агентов и он превращается в 10 мегабайт. Каждый аллоцированный килобайт превращается в 10 гигабайт и вычисление будет падать с Out Of Memory.

Например: ты вызываешь какую-нибудь невинную функцию, типа neighbours(agent) , которая возвращает массив соседей данного агента. Под капотом она может быть устроена как-то так
function neighbours(agent)
   1. Создать массив, в котором будем накапливать результат
   2. с помощью какого-нибудь более-менее продвинутого пространственного индекса обежать окрестность агента, если в ней находятся другие агенты, то `push!` их в промежуточный массив
   3. Вернуть массив агентов

Понятно, что начинка может меняться, но основная мысль, которую хочу сказать - в этом подходе аллоцируется массив, потом он ещё несколько раз переаллоцируется когда push! пытается его растянуть.
Хотя массив будет хранить только указатели на агентов, это всё равно 8 байт на агента + оверхед от самого массива. Если у тебя в среднем 10 соседей, то это уже получится в районе 100 байт на один вызов. Умножаем на 10 миллионов агентов, и...

Правильная версия разумеется в состоит в создании контейнера, который будет переиспользоваться
function neighbours!(neighbours_container, agent)
1. создаем инкрементную переменную i, которая указывает куда будет записываться новый сосед.
2. Пробежать по окрестности агента, находя соседей, записываем их в neighbours_container, инкрементим переменную i
3. Возвращаем neighbours_container (хотя это уже опционально)


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

S

Serg in Язык программирования Julia / Julia programming language
Roman Chebotarev
ого! Спасибо за такой развернутый ответ. О некоторый моментах я даже не задумывался
Поддерживаю. Даже не сталкиваясь с такими задачами мне очень нравится читать такие ответы. Спасибо, что пишите👍
источник

RC

Roman Chebotarev in Язык программирования Julia / Julia programming language
Немного оффтоп для чата, но в продолжение про симуляцию - вот буквально вчера ряд известных чуваков из AI-индустрии анонсировали, что пилят https://hash.ai/ платформу для сложных симуляций на замену всяким AnyLogic и симуляторам "из двухтысячных". Записался в бета-тестеры )
источник

VG

Viktor G. in Язык программирования Julia / Julia programming language
для неаллоцирующего контейнера фиксированной максимальной длины подойдет a = CircularDeque{Int}(n) или CircularBuffer из DataStructures.jl
источник

VG

Viktor G. in Язык программирования Julia / Julia programming language
но лучше конечно статические массивы использовать - они живут на стеке
источник

KT

Kirill Tsaregorodtsev in Язык программирования Julia / Julia programming language
Viktor G.
но лучше конечно статические массивы использовать - они живут на стеке
Что такое статические массивы? StaticArrays ?
источник

KT

Kirill Tsaregorodtsev in Язык программирования Julia / Julia programming language
насколько их уместно использовать при длине массива в миллион элементов скажем?
источник

VG

Viktor G. in Язык программирования Julia / Julia programming language
да, они https://github.com/JuliaArrays/StaticArrays.jl
Их лучше использовать для малых размеров типа 10 элементов или около того. Когда-то рекомендовали использовать для всего, что меньше 100, но с тех пор вроде обычные массивы стали быстрее.
источник