SWI-Prolog threads with stream output

落爺英雄遲暮 提交于 2019-12-12 15:58:37

问题


If I have a program like the one below, does prolog try to prove maximum/3 all three times in parallel? i.e does each thread get its own core (assuming available on the computer)?

My actual program takes about 2 hours to run a predicate in the position of maximum/3 here and I have 70 equivalent of pair/2 that will need to be calculated. Would this approach work? If not why not? I have set the program running but it seems from the output that it is just doing one thread at a time.

maximum(X,Y,Y) :- X =< Y,!.
maximum(X,_,X).

pair(5,6).
pair(8,7).
pair(9,9).


thread(A,B,Stream) :-
  maximum(A,B,C),
  format(Stream, "max('~w','~w',~w).~n",[A,B,C]),
  thread_exit(C).


start(File) :-
  open(File,append,Stream,[]),
   forall(
      pair(A,B),
      (
       thread_create(thread(A,B,Stream),Id,[]),
       thread_join(Id,exited(X)),
       writeln(X)
      )
     ),
  close(Stream).

回答1:


You can simplify your code by taking advantage of the SWI-Prolog concurrent/3 library predicate:

http://www.swi-prolog.org/pldoc/doc_for?object=thread:concurrent/3

Another option is Logtalk's support for high-level multi-threading programming (SWI-Prolog is one of the backend Prolog compilers it supports).

In any case, it's a two step process: first create the goals (that should be executed in parallel) and, second, run them. But you're not doing that. SWI-Prolog threads are created (by default) as non-detached. The call to thread_join/2 predicate in your code means that you're waiting for the thread you just created to finish before passing to the next pair. Thus, you're correct and your code is running one thread at a time. Try:

maximum(X,Y,Y) :- X =< Y,!.
maximum(X,_,X).

pair(5,6).
pair(8,7).
pair(9,9).

thread(A,B,Stream) :-
  maximum(A,B,C),
  format(Stream, "max('~w','~w',~w).~n",[A,B,C]).

start(File) :-
  open(File,append,Stream,[]),
  findall(thread(A,B,Stream), pair(A,B), Goals),
  length(Goals, N),
  concurrent(N, Goals, []),
  close(Stream).

Sample execution:

?- [concurrent].
true.

?- start(results).
true.

?- 
% halt
$ cat results
max('5','6',6).
max('8','7',8).
max('9','9',9).

Using the number of goals as the number of threads (aka workers) to use is, however, not the best choice. Likely better to use a value for N derived from the number of cores (or the number of threads each core can run) of your hardware.

The Logtalk solution is similar (but more portable) using its threaded/1built-in predicate (but it takes a goal conjunction instead of a goal list).



来源:https://stackoverflow.com/questions/26849346/swi-prolog-threads-with-stream-output

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!