On 4/3/2012 9:46 AM, Miles Fidelman wrote:
David Barbour wrote:
On Tue, Apr 3, 2012 at 8:25 AM, Eugen Leitl <[email protected]
<mailto:[email protected]>> wrote:
It's not just imperative programming. The superficial mode of human
cognition is sequential. This is the problem with all of mathematics
and computer science as well.
Perhaps human attention is basically sequential, as we're only able
to focus our eyes on one point and use two hands. But I think humans
understand parallel behavior well enough - maintaining multiple
relationships, for example, and predicting the behaviors of multiple
people.
And for that matter, driving a car, playing a sport, walking and
chewing gum at the same time :-)
yes, but people have built-in machinery for this, in the form of the
cerebellum.
relatively little conscious activity is generally involved in these
sorts of tasks.
if people had to depend on their higher reasoning powers for basic
movement tasks, people would likely be largely unable to operate
effectively in basic day-to-day tasks.
If you look at MPI debuggers, it puts people into a whole other
universe of pain that just multithreading.
I can think of a lot of single-threaded interfaces that put people in
a universe of pain. It isn't clear to me that distribution is at
fault there. ;)
Come to think of it, tracing flow-of-control through an
object-oriented system REALLY is a universe of pain (consider the
difference between a simulation - say a massively multiplayer game -
where each entity is modeled as an object, with one or two threads
winding their way through every object, 20 times a second; vs.
modeling each entity as a process/actor).
FWIW, in general I don't think much about global control-flow.
however, there is a problem with the differences between:
global behavior (the program as a whole);
local behavior (a local collection of functions and statements).
a person may tend to use general fuzzy / "intuitive" behavior for
reasoning about "the system as a whole", but will typically use fairly
rigid sequential logic for thinking about the behavior of a given piece
of code.
there is a problem if the individual pieces of code are no longer
readily subject to analysis.
the problem I think with multithreading isn't so much that things are
parallel or asynchronous, but rather that things are very often
inconsistent.
if two threads try to operate on the same piece of data at the same
time, often this will create states which are impossible had either been
operating on the data individually (and, very often, changes made in one
thread will not be immediately visible to others, say, because the
compiler had not actually thought to write the change to memory, or the
other thread to reload the variable).
hence, people need things like the "volatile" modifier, use of atomic
operations, things like "mutexes" or "synchronized" regions, ...
this leaves several possible options:
systems go further in this direction, with little expectation of global
synchronization unless some specific mechanism is used (two threads
working on a piece of memory may temporarily each see their own local copy);
or, languages/compilers go the other direction, so that one thread
changing a variable is mandated to be immediately visible to other threads.
one option is more costly than the other.
as-is, the situation seems to be that compilers lean on one side (only
locally consistent), whereas the HW tries to be globally consistent.
a question then, is assuming HW is not kept strictly consistent, how to
best handle this (regarding both language design and performance).
however, personally I think abandoning local sequential logic and
consistency, as being a bad move.
I am personally more in-favor of message passing, and either the ability
to access objects synchronously, or "pass messages to the object", which
may be in-turn synchronous.
consider, for example:
class Foo
{
sync function methodA() { ... } //synchronous (only one such
method executes at a time)
sync function methodB() { ... } //synchronous
async function methodC() { ... } //asynchronous / concurrent
(calls will not block)
sync async function methodD() { ... } //synchronous, but calls will
not block
}
...
var obj=new Foo();
//thread A
obj.methodA();
//thread B
obj.methodB();
the VM could enforce that the object only executes a single such method
at a time (but does not globally lock the object, unlike "synchronized").
similarly:
//thread A
async obj.methodA();
//thread B
async obj.methodB();
which works similarly, except neither thread blocks (in this case, "obj"
functions as a virtual process, and the method call serves more as a
message pass). note that, if methods are not "sync", then they may
execute concurrently.
note that "obj.methodC();" will behave as if the async keyword were
given (it may be called concurrently). "obj.methodD();" will behave as
if it were a synchronous method called asynchronously.
this allows deliberately asynchronous behavior (and more ability to
optimize for a multi-processor system), but at the same time, does not
hinder the use of synchronous logic.
similar behavior can be applied to blocks:
async { ... } //block does not block
sync { ... } //block will block
as-is, most of this stuff uses "green threads" (and some amount of
internal locking), so it is less certain how to best map it to real HW.
I can imagine some how to map it to either "CPUs with inter-processor
interrupts", or to something like TCP or UDP, which could be "close
enough" (like, if a hugely multiprocessor system were implemented in a
form resembling a bunch of simpler shared-memory multiprocessor systems
connected over a network or similar).
FWIW, as-is, I don't really make all that intensive use of
multithreading. my code is, technically, multithreaded, but most of the
code is itself still largely single-threaded, and most threads are based
on "subdivision by task" rather than "parallel execution".
for example:
a thread to manage the GC;
another thread to manage the "TRNG". it tries to generate true random
numbers based on the assumption that the noise patterns seen in "rdtsc"
deltas represent "true" entropy (basically, it is a loop which does
little more than sleep and call rdtsc, and add the values seen into a
random number generator);
also the VM green-thread workers, and several other misc threads.
a recent consideration was to move video recording/encoding to its own
thread, due to the apparent lag-inducing behavior of the current video
recording (which operates in the same thread as my 3D renderer,
resulting in a notable drop in framerate whenever video recording is
active). granted, this is partly because I am using MJPG, and my JPEG
encoder has a hard time keeping up with encoding full-resolution
(800x600 in this case) screen-shots in a timely manner:
individually, both the video recording and 3D renderer pull off around
40fps, but when used together, the overall framerate is more around
10-15fps.
yes, it is much faster to dump truecolor video to disk, but this rapidly
eats up HDD space (around 1GB/min with 16bpp output). blarg...
currently, video-recording isn't a major use-case though.
or such...
_______________________________________________
fonc mailing list
[email protected]
http://vpri.org/mailman/listinfo/fonc