Моя проблема: применить предикат для фильтрации списка параллельно
У меня есть список, и у меня есть предикат. На практике это длинный список, и предикат требует времени. Я хочу вывести только те элементы списка, которые удовлетворяют предикату.
У меня есть доступ к большому количеству процессорных ядер, поэтому я подумал, что имеет смысл попытаться параллельно протестировать элементы списка блоками.
Материал, который я пробовал:
[concurrent_
]maplist
не работает
Вроде должно быть легко. concurrent_maplist
кажется простой параллельной версией maplist
.
Согласно другому ответу на этом сайте, maplist/3
должен делать именно то, что я хочу. Документация для SWI maplist/3
предполагает, что он не работает как описано в ответе, но в комментариях автор ответа предполагает, что это проблема с документами, и она действительно должна работать так, как ожидалось.
Кажется, это не работает для меня.
Я проверил это следующим образом:
:- use_module(library(apply)).
f(A):-
(A*A < 10),
writeln(A).
set(0,[]).
set(N,T):- N2 is N-1, set(N2,T1), append(T1,[N],T).
Это не работает:
?- set(4,L), concurrent_maplist(f, L, O).
ERROR: Undefined procedure: f/2
ERROR: However, there are definitions for:
ERROR: f/1
Та же проблема с обычным maplist
:
set(4,L), maplist(f, L, O).
ERROR: Undefined procedure: f/2
ERROR: However, there are definitions for:
ERROR: f/1
include
работает, но не параллельно
Что делает то, что я хочу (но не параллельно), это include
:
?- set(11,L), include(f, L, O).
1
2
3
L = [1, 2, 3, 4, 5, 6, 7, 8, 9|...],
O = [1, 2, 3] .
concurrent
[править] бежит! Но параллельно?
Я пытался заставить его работать, используя concurrent/3
частично по примеру другого ответа.
Загрузка этого файла:
set(0,[]):-!.
set(N,T):- N2 is N-1, set(N2,T1), append(T1,[N],T).
f(A, B):-
(A*A < B),
writeln(A).
par_test(A, B):-
set(A, S),
findall(f(Good, B), (member(Good, S)), Goals),
concurrent(8, Goals, []).
...
?- set(4, S), findall(f(Good, 4), member(Good, S), Goals), concurrent(8, Goals, []).
1
false.
Но наблюдая за htop
(с гораздо более длинным предикатом вместо этого f
), кажется, что он работает только на одном ядре :-(.
Как сделать это параллельно?
Есть ли способ добиться этого с помощью concurrent_maplist
или аналогичной простой параллельной версии include
, или другого способа добиться того, что я собираюсь сделать?