Skip to content

Instantly share code, notes, and snippets.

@haxney
Last active December 25, 2015 01:19
Show Gist options
  • Save haxney/6894737 to your computer and use it in GitHub Desktop.
Save haxney/6894737 to your computer and use it in GitHub Desktop.
extern mod extra;
use extra::future::Future;
use std::num;
/**
* Speculatively execute consumer using the guessed value.
*/
pub fn spec<A: Eq + Send, B>(producer: ~fn() -> A,
predictor: ~fn() -> A,
consumer: ~fn(x: &A) -> B) -> B {
let producer_result = Future::spawn(producer);
let prediction = predictor();
let speculative_result = consumer(&prediction);
let real_value = producer_result.unwrap();
if real_value == prediction {
speculative_result
} else {
consumer(&real_value)
}
}
pub fn specfold<A: Eq + Clone + Send>(low: int,
high: int,
loopBody: ~fn(int, ~A) -> A,
predictor: ~fn(int) -> A) {
let len = num::abs(high - low) as uint;
// The future is (prediction, result)
let mut results: ~[Future<(~A, ~A)>] = std::vec::with_capacity(len);
for i in range(low, high) {
let p = |i| predictor(i);
let l = |i, prediction| loopBody(i, prediction);
let fut = do Future::spawn_with((p,l)) |(p,l)| {
let prediction = p(i);
(~prediction.clone(), ~l(i, ~prediction.clone()))
};
results.push(fut);
}
// Validate. Sequentially, for now
for i in range(low + 1, high) {
let (_, previous) = results[(i - low) - 1].get();
let (prediction, _) = results[i - low].get();
if previous != prediction {
results[i - low] = Future::from_value((~(*previous).clone(),
~loopBody(i, ~(*previous).clone())));
}
}
}
extern mod speculate;
use speculate::*;
#[test]
fn simple() {
assert!(spec(|| 2 + 2, || 4, |x:&int| x + 2) == 6);
assert!(spec(|| 2 + 2, || 1, |x:&int| x + 2) == 6);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment