Ocaml выполнение программы не производит новый вывод через некоторое время - PullRequest
0 голосов
/ 10 апреля 2019

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

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

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

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

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

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

$ ./test.exe > file

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

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

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

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

1 Ответ

1 голос
/ 10 апреля 2019

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

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

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

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

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

...