【问题标题】:Prolog memory issuesProlog内存问题
【发布时间】:2013-04-04 13:00:41
【问题描述】:

我想找到一种方法来分析我在 prolog 中编写的谓词(一个巨大的谓词)的内存使用情况。我目前正在使用swiyap 运行它,我可以从这些进程的内存消耗中看到分配了大量内存。

问题是当谓词终止时它没有被释放/释放/垃圾收集(我必须停止解释器才能看到它)加上内存量只会保持增长,而谓词正在运行(它是否不应该运行,因为尾递归优化应该在每次迭代时缓解这个问题)。

有没有办法发现增加内存使用的子谓词/调用并检查是否有效地调用了尾递归优化?

任何其他关于如何优化问题的建议将不胜感激。如果有必要,我将提供有关谓词正在做什么的更多详细信息。

【问题讨论】:

    标签: prolog profiling swi-prolog yap


    【解决方案1】:

    在 SWI-Prolog 中,查看递归谓词是否真正得到尾部优化的一种简单方法是使用 prolog_current_frame (look here):

    foo :-
        prolog_current_frame(F), format('~d~n',[F]),
        do_something,
        foo.
    

    如果执行了尾部优化,每次您通过递归调用输入谓词时,它将返回相同的整数。我遇到的问题是我没有意识到我正在使用的谓词正在创建选择点并阻止尾部优化。

    如果没有尾部优化是实际问题,那么您可以做的其他事情就是在递归调用之前放置一个剪切:

    foo :-
        do_something,
        !, foo.
    

    这将删除do_something 创建的所有选择点。如果您的内存使用量仍在增长,那么问题可能出在其他地方。您的谓词是否创建了大型数据结构?还是使用很多中间列表?

    【讨论】:

    • 感谢您提供有关发现最后一次呼叫优化的提示。检查未优化代码的一种简单且手动的方法是在每个周期中调用 prolog_current_frame/1。我看到谓词也被 yap 识别,但它的值有时会发生变化(它与添加 cut 的 swi 不同)所以我猜它不可靠(我现在正在运行它来检查内存消耗它会需要 1 小时 :))
    • 基本上我正在做一些 ILP 工作,从一个大文件中加载约 7000 个示例(作为每个约 500 个文字主体子句),并对我目前最好的假设进行概括/改进,以解释所有这些.我在每次迭代中大量使用关联列表并创建/处理长列表。
    • @rano 这确实是我的意思,每次循环调用prolog_current_frame(Frame)Frame 不应该改变是执行了尾部优化。我不知道这是否适用于 YAP。
    • 我想我不会再收到任何关于对我的 prolog 程序进行内存分析的方法的回复,所以我会将这个答案标记为正确的答案,因为它部分满足了我的需求并且对解决一个非常有用我的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多