我目前正在进行理论计算机科学的一些研究,我正在使用的主要工具之一就是序言。我发现编写非常快速的测试以反驳猜想特别方便。
然而,我已经到了蛮力搜索速度太慢的地步。虽然我可以使用不同的语言,但我使用prolog的重点是编写代码以测试假设的速度非常快/简单。
我想知道,是否有Prolog的实现允许自动并行化?它不一定要快速剃刀,但理想情况下我正在寻找一些我可以放弃我的代码并至少获得一个小加速的东西。
我不知道这是否可行。谷歌搜索在Prolog中发现了很多关于自动并行的学术文章,但我没有遇到任何实现。但是,我真的只熟悉SWI-prolog,所以我绝对可以使用熟悉许多实现的人的建议。
我的代码使用剪切,但我相信我可以消除它们。至于IO,唯一的IO是打印到控制台,可能会移动到任何并行代码之外。
答案 0 :(得分:5)
你确定你需要并行来“至少获得一个小的加速”吗?
你说你只熟悉SWI-Prolog,所以试试其他Prolog系统。根据{{3}}的基准测试结果(可能与您的特定问题相关或不相关),您应该尝试B-Prolog,YAP和SICStus-Prolog(这个不是免费的)。如果你很幸运,只需切换你的Prolog系统就可以获得几倍的加速。
另一种可能的低成本加速方式 - 使用具有表格支持的系统(B-Prolog,XSB或YAP),并添加:- auto_table.
之类的东西作为程序的第一行。根据您的问题和现有程序,您可以获得显着的加速(或者根本没有加速)。
答案 1 :(得分:3)
使用Prolog并不难发现并行性,很难选择使用哪种并行;)。
也许Parlog - logic based programming language, designed for parallel execution会对你有所帮助。有implementation for windows但我不确定它是否使用多个核心。但是你可以尝试联系那里的作者。
答案 2 :(得分:1)
在Jekejeke Prolog中,我尝试使其尽可能简单 为程序员提供了一个简单的结构,称为balance / 1。 对于balance / 1,会产生并测试问题:
/* sequential */
?- Generate, Test.
将分布在多个线程上。发票为 就像将谓词包装到谓词balance / 1中一样简单。 结果可能需要重新排序:
?- use_module(library(runtime/distributed)).
/* parallel */
?- balance((Generate, Test)).
这里是素数并行生成的示例。的 顺序代码如下:
:- use_module(library(advanced/arith)).
prime(N) :-
M is floor(sqrt(N)),
between(2,M,K),
N mod K =:= 0, !, fail.
prime(_).
?- time(aggregate_all(count,
(between(1,1000000,X), prime(X)), N)).
% Up 6,737 ms, GC 33 ms, Thread Cpu 6,656 ms (Current 07/16/19 01:49:02)
N = 78499
并行执行操作会得到:
?- time(aggregate_all(count,
balance((between(1,1000000,X), prime(X))), N)).
% Up 4,167 ms, GC 39 ms, Thread Cpu 219 ms (Current 07/16/19 01:49:50)
N = 78499
因此可以加快速度,因为该问题可以在多个线程上运行。