Last active
December 20, 2015 04:29
-
-
Save mndrix/6071506 to your computer and use it in GitHub Desktop.
Toying with Amalog concurrency
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ack +Dir +Language +Pattern -File -Line | |
// | |
// True if File is beneath the directory Dir, written in Language and contains | |
// a Line that matches Pattern. Similar to the command line tool ack. | |
ack Dir Language Pattern File Line | |
dir_entry Dir Entry | |
type Entry file | |
fan_out 1 // optional optimization. See Note_fan_out | |
language Entry Language | |
line Entry Line | |
Line ~~ Pattern | |
// The concurrent_generator declaration says "generate choicepoints from dir_entry/2 | |
// independently, buffering up to 4 results at a time, allowing the calling code to | |
// investigate choice points concurrently as they're created" | |
// | |
// Internally, this is sort of like creating a goroutine for dir_entry/2 and having | |
// it send solutions down a channel to the main thread of execution. This is done | |
// with a directive because the predicate is most likely to know how slowly it will | |
// generate choicepoints. A predicate like between/3 wouldn't use concurrent_generator. | |
// | |
// The idea is that one can write a predicate just as one normally would. When he | |
// learns that it can benefit from concurrency, he adds this single directive and realizes | |
// performance improvements. | |
:- concurrent_generator 4 dir_entry/2 | |
... | |
// Note_fan_out: | |
// The goal fan_out/1 tells the runtime that outstanding choicepoints should be | |
// investigated concurrently with up to N threads per core. It's a way of | |
// saying, "We've created choicepoints for every possible solution, searching | |
// each choicepoint is going to be slow, so use multiple cores to make it faster" | |
// | |
// It doesn't matter how the choicepoints were created. If a cut discards some | |
// choicepoints that are being investigated in a separate thread, those threads | |
// stop and their work is discarded. In that scenario, it allows speculative | |
// execution. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
main | |
maplist | |
spawn factor // spawn is an optional optimization | |
[huge,numbers,go,here] | |
ManyFactors | |
do_something_with_factors ManyFactors | |
// factor +N -Factors | |
// | |
// True if N is composed of a list of prime Factors. | |
// This predicate is expensive for large N. | |
// spawn/N is like call/N except it creates a communicating sequential process | |
// to seek the goal. spawn returns immediately. Each solution the process | |
// finds is communicated by binding variables in the spawning process. If | |
// the spawning process tries to unify with a variable whose value comes from | |
// a spawned process, it blocks until the value is available. If no solutions | |
// are found, unification fails. | |
// | |
// This technique is conceptually similar to Go's goroutines and channels except | |
// the details are all implicit. One achieves concurrency by simply wrapping an | |
// existing goal in spawn/N. Details like channels, receiving values, unpacking | |
// values, closing channels, are all done automatically by the runtime. | |
// | |
// One weakness of this model is that communication is only from child to parent. | |
// There's no mechanism for the spawning process to communicate additional | |
// information to the spawned process. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment