Completely transparent concurrency is possible through
speculative execution
/evaluation. I am not certain if there is research on how much gains are typically realized with speculative execution (although it is certainly utilized at a lower level in processors for performance gains). But if one wrote a speculative execution optimization for a ES VM that executed future functions by tracking all memory reads and restarted (the speculation) if any of that memory changed, and blocked anytime memory was to written outside of the current speculated scope (or logged memory writes in virtual log to be later committed when the speculate branch was vindicated), one could certainly do transparent concurrency (similiar to STM techniques). (
http://www.cs.wisc.edu/~rajwar/papers/micro01.pdf
describes this technique for synchronized/critical sections of multithreaded thread. In a single-threaded model essentially all execution is a synchronized including speculative branch or other fibers). One could easily see how such speculation could improve the following code with no hazards or side effects:
function prime(number) {
for (var i = 0; i < sqrt(number);i++)
if (number % i == 0)
return false;
}
function fermats() {
fermatNumbers = [];
fermatNumbers[0] = prime(2+1);
fermatNumbers[1] = prime(2^2+1);
fermatNumbers[2] = prime(2^2^2+1);
fermatNumbers[3] = prime(2^2^2^2+1);
fermatNumbers[4] = prime(2^2^2^2^2+1);
return fermatNumbers;
}
In this case, speculative execution can look ahead and execute the prime function. The speculative can proceed with the caution of restart anytime it reads shared memory that gets later changes (the prime function doesn't end up reading any shared memory), and stopping for writing of shared memory (prime doesn't write any shared memory either).
Lazy evaluation is a similiar approach, and but from a different perspective on the same strategy. In lazy evaluation it is possible for the VM to evaluate a function in separate thread and keeping a promise/future as the return value until it is needed. However, without any assurance that the lazy function will not write any data, the thread that is executing ahead of the lazy function must effectively operate like a speculative thread, no shared memory writes, and restarts if any of it's read memory is altered.
Actually, code that is designed to not use any shared memory (outside of it's own scope) effectively becomes a concurrently running process with speculative execution. The performance drawback is that the speculative execution must track memory reads and writes to determine share conflicts, whereas in a erlang style message passing architecture, it is just impossible to even reference shared memory, so nothing ever needs to be checked. But, if memory writes outside of the local scope are few or nonexistent, the concurrent process can run quite efficiently. And speculation is transparent...
I presume that with your (Brendan) positive references to non-shared memory models, that you aren't that big on STM, at least in it's model of defaulting to shared memory, and explicitly define blocks of atomicity?
However, if you look at STM from the perspective of considering all ES execution to be atomic by default, unless otherwise stated, you can use STM with the resulting decomposed atomicity to facilitate STM optimization. If you implemented fibering, the yield points of a fiber would be the boundary points of the STM transactions. Ironically, I believe in the end this would actually be very similiar to the speculative execution in combination with fibers (and with a speculation bias towards other fibers). STM is the basically the same as speculative execution in its memory protection technique (processing without side-effects until it is safe to commit side-effects).
Authenteo 1.1 is available.
Now with
Firebug integration
. Make changes to CSS and HTML with Firebug and save the changes
Check out press releases and the following articles on Authenteo: