-3

In Practical Foundation of Programming Languages

38 Futures and Speculations

A future is a computation that is performed before it is value is needed. Like a suspension, a future represents a value that is to be determined later. Unlike a suspension, a future is always evaluated, regardless of whether its value is required. In a sequential setting, futures are of little interest; a future of type τ is just an expression of type τ. In a parallel setting, however, futures are of interest because they provide a means of initiating a parallel computation whose result is not needed until later, by which time it will have been completed.

A speculation is a delayed computation whose result might be needed for the overall computation to finish. The dynamics for speculations executes suspended computations in parallel with the main thread of computation, without regard to whether the value of the speculation is needed by the main thread. If the value of the speculation is needed, then such a dynamics pays off, but if not, the effort to compute it is wasted.

Futures are work efficient in that the overall work done by a computation involving futures is no more than the work done by a sequential execution. Speculations, in contrast, are work inefficient in that speculative execution might be in vain—the overall computation may involve more steps than the work needed to compute the result. For this reason, speculation is a risky strategy for exploiting parallelism. It can make use of available resources, but perhaps only at the expense of doing more work than necessary!

38.3 Parallel Dynamics

Futures are only interesting insofar as they admit a parallel dynamics that allows the computation of the future to go ahead concurrently with some other computation. In this section, we give a parallel dynamics of futures and speculation in which the creation, execution, and synchronization of tasks is made explicit. The parallel dynamics of futures and speculations is identical, except for the termination condition. Whereas futures require that all tasks are completed before termination, speculations may be abandoned before they are completed.

Both futures and speculations are evaluated, regarless of whether their values are needed. So how are futures more efficient than speculations?

What does it mean by "futures require that all tasks are completed before termination, speculations may be abandoned before they are completed"?

I still don't understand how futures and speculations are evaluated differently.

Thanks.

1
  • These terms are not universally used with those specific meanings. The terminology might be in part specific to the book you're reading. When you come across a term like promise or future in an API or document, you should read its specific definitions. Evaluation mechanics also differ drastically between languages, e.g. Rust futures don't make progress unless they are awaited/polled but JavaScript promises are fire and forget, and can be used for background IO tasks. Commented Feb 13, 2021 at 17:43

2 Answers 2

2

They're actually evaluated the same.

The key is to ignore whatever it is the language or the library you're using calls it and concentrate on the design of the software firing off the parallel operations, and the intent of the programmer thereby.

If you know you're going to use the result of the computation in the future and you want to have it ready when you eventually need it and you've got the processors to run the computation on, so your goal is to reduce latency, then it is a future. You're definitely going to use the result so the CPU cycles aren't going to be wasted, that is, there's no better use to put them to then to calculate something you need.

But maybe you don't absolutely need the result in the future but you think under some circumstances (depending on what might happen in the next few cycles...) you might need it - and if you do need it you're going to want it right away (to reduce latency when and if you need the result). Then it is a speculation - you're anticipating a possible advantage - and if it turns out you do need the result well and good, but if it happens that you don't need it after all then those CPU cycles were wasted and you might have been able to use them for something else if you had predicted the future better, or if you had had computations you positively needed to perform that you had to delay (and got later) because a processor was busy on your speculative work.

In practice concurrent libraries may or may not let you cancel an in-progress computation anyway. Frequently you can't because the underlying mechanism - maybe a (userspace) thread - can't actually be cancelled. (Because it is in general unsafe to simply stop a userspace thread and delete its resources - it might be holding a lock or some kernel thing that then would never be closed/freed.) So you might find that libraries that call their constructs futures (with corresponding promises) don't have any ability to cancel and you either have to join with all your futures or access all your promises before you can exit. And in libraries like that - you may very well want to speculate and fire off computations before you need them in the hope of needing them - but choose well and try not to do it too much - unless you're swimming in processors ...

2

A speculation isn't a very common term from a programmer's point of view, but my understanding is they are evaluated identically to a future. The difference is in what you do with the result.

To restate in more familiar terms, what they call a "future" appears to be like an async function that is always awaited. A "speculation" is like an async function that you start in case its result will be useful, but you don't have the information yet to know if you want to await it or not. If you decide not to await it, the cpu time you spent running it ends up getting wasted.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.