Выполнение программы Ocaml не производит новый вывод через некоторое время

У меня есть 3 модуля ocaml, последний из которых выполняет фактические вычисления и использует функции, определенные в двух других.

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

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

Когда я запускаю программу следующим образом:

$ ocamlc -o test.exe port.ml moves.ml solver.ml
$ ./test.exe > file

Полученный файл действительно огромен, но его размер через некоторое время перестает увеличиваться. Мне кажется, что через некоторое время программа перестает работать, но без завершения, не выдается ошибка Stackoverflow или нехватка памяти. Программа просто не продолжает выполнение. Другими словами, команда

$ ./test.exe > file

все еще выполняется, но в файл больше не добавляются новые строки. Если я захожу в саму оболочку, а не в файл, я получаю тот же результат: через некоторое время новые строки не добавляются.

Что бы это могло быть?

Основная функция (отвечающая за поиск решения) использует алгоритм поиска в глубину и содержит много операций со списком, таких как List.fold, List.map, List.iter, List.partition, List.filter. Я думал, что, возможно, у этих функций есть проблемы с обработкой огромных списков сложных типов в какой-то момент, но опять же, никакой ошибки не выдается, выполнение просто останавливается.

Я объяснил это очень расплывчато, но я действительно не понимаю проблемы здесь. Я не знаю, связана ли проблема с моей оболочкой (подсистема Ubuntu в Windows) с нехваткой памяти или с ограничениями функций списка ocaml в какой-то момент... Если у вас есть какие-либо предложения, не стесняйтесь комментировать

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

Konstantin Strukov 10.04.2019 13:30

Спасибо. Я посмотрю, смогу ли я предоставить код.

charelf 10.04.2019 13:33

Обновление: я не обновлял ответ кодом, так как это, вероятно, не привело бы к решению. Решение, вероятно, заключается в том, что код все еще работал в фоновом режиме, а мой алгоритм настолько медленный, что кажется, что он завис.

charelf 12.04.2019 16:15
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
59
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Для отладки таких случаев следует использовать диагностические утилиты, предоставляемые вашей операционной системой и самой инфраструктурой OCaml.

Прежде всего, вы должны изучить состояние вашего процесса. Вы можете использовать утилиты top или htop, если вы используете машину Unix. В противном случае вы можете использовать диспетчер задач.

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

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

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

Другие вопросы по теме