On 8/3/2011 1:04 PM, Igor Stasenko wrote:
On 3 August 2011 21:04, BGB<[email protected]> wrote:
sorry, just trying to clarify a few points...
...
sadly, the "async" modifier was used in the first incarnation of BGBScript
(2004-2006), but was never fully reimplemented when the language was later
re-implemented (it has been on a long-term to-do list, but there were many
more pressing features to get implemented, and alternative if albeit less
convenient mechanisms exist...).
the issue is granted, not so much whether one can type, say:
for(i=0; i<100; i++)
fun(i) { async printf("%d\n", i); } (i);
but whether or not it will "own" their computer in the process...
(note: ugly closure hack needed to give each thread a proper unique value
for 'i', again probably another weak point of the existing model).
except that, as written, the above would not "own" ones' computer, due to a
few details:
the threads are too short-lived, so a momentary 100% CPU spike on all cores
would not likely be noticed too badly;
using a "soft" threading model, likely only a single worker OS thread would
spawn which would service all of the threads, very possibly sequentially
(the threads are likely too short-lived to trigger additional workers to
spawn);
with soft threading, the memory use is likely to be fairly trivial (nowhere
near crash-risk levels);
a larger number of OS threads would be needed to threaten the program
(500-700 would likely crash a 32-bit the process on Windows, but the OS
would probably survive this, 200-400 would likely crash a 32-bit Linux
process, in both cases likely due to running out of address-space).
so, I guess it can be more taken "in principle" that naively spawning a
large number of OS threads could crash stuff...
yes, especially by taking into account that you cannot run more
threads (in parallel) than
existing cores. So, it is pointless to spawn more than hardware can do, because
these threads will just wait own turn to claim one of free cores and
meanwhile just consume resources,
which allocated by system for each thread: stack and thread state.
yep, hence part of why it makes sense to try to be sparing with these
OS-level threads: they are not exactly cheap, and don't really
contribute to performance past the number of cores.
looked it up, it turns out my "soft" threads are more commonly called
"green threads".
also possible is to do something similar to fibers, which can
essentially be managed by the same worker threads as the the
green-threads (likewise, it is assumed that they are short-lived, and
are much more light-weight if they don't have their own dedicated stacks).
Especially pointless for cases, when workload is comparable to
scheduling overhead. It means that running loop sequentially
could even produce results faster than scheduling 500-700 parallel tiny jobs.
IMO, high-granularity parallelism is road to nowhere.
yes, although latency may be an issue, and there are cases, say, where
several more workers can deliver a bit better latency (or, worst case,
scripts are calling into long-running C functions via the FFI,
essentially stalling workers).
however, if one is needing a large number of workers, probably something
has gone terribly wrong.
another mystery is if the work-dispatcher needs its own thread, rather
than being monitored by the main GC-loop thread (monitors heap-usage /
... and triggers the GC when needed, or when requested explicitly by
either the client program or the memory allocator failing to find memory).
having them in the same thread should be fine.
the job of the work-dispatcher is essentially to spawn off worker
threads in cases where the work-queue has stuff in it and it is not
getting serviced in a timely manner.
yeah, my GC sort of also doubles as a thread-manager...
actually, the GC library also contains logging facilities and a random
number generator as well.
another idle thought is if a language that already has dynamic scope
actually needs TLS as well.
the issue is that having both could be needlessly redundant.
there are possible tradeoffs, so it may need more evaluation.
slight (possible/eventual) syntax sugar could be something like:
for(i=0; i<100; i++)
async(i) printf("%d\n", i);
with the semantics that "i" is captured at the point the statement is seen,
essentially turning the operation into a lambda-block and an async call
operation. also this would save 1 code block vs the prior form (both async
and closures use blocks, using both thus requires 2 blocks, but a combined
form would only need a single block).
note that otherwise, the variable will be captured, rather than its value,
hence the "printf" call would see whatever was the last value in the
variable. it is then necessary to "capture" its value at the point of
execution so that the explicit value at that moment is captured.
note, the effective opposite of "async" (or "thread", if added) would be
"synchronized", as in:
"synchronized { ... }" which would use a mutex (or some other means) to
synchronize execution within a given block.
it can also be (theoretically) applied to methods and classes (sadly also
not presently implemented).
now whether any of this could make threading easier to use... I really
have little idea...
my good old friend implementation holes.
this is because I can sometimes spec out more features than I have
implemented, or older features can "fall off a ledge" somewhere (say, when
doing a mostly ground-up reimplementation of ones' VM).
maybe there is some fundamentally better way to approach multi-threaded
code?...
still a mystery...
maybe in a more ideal world, maybe everything could just be converted to CPS
and executed wherever a worker was available (essentially blurring the line
between single and multithreaded code). however, how to best express and
work with concurrent code is still an issue though.
_______________________________________________
fonc mailing list
[email protected]
http://vpri.org/mailman/listinfo/fonc
_______________________________________________
fonc mailing list
[email protected]
http://vpri.org/mailman/listinfo/fonc