Re: Parrot multithreading?
On Thu, 20 Sep 2001 14:04:43 -0700, Damien Neil wrote: On Thu, Sep 20, 2001 at 04:57:44PM -0400, Dan Sugalski wrote: For clarification: do you mean async I/O, or non-blocking I/O? Async. When the interpreter issues a read, for example, it won't assume the read completes immediately. That sounds like what I would call non-blocking I/O. Nonono. Nonblocking IO returns immediately. Async IO lets the interpreter go on with another thread, until the read is done. -- Bart.
Re: Parrot multithreading?
At 03:59 PM 9/20/2001 +0200, Arthur Bergman wrote: While it has been decided that perl should be using ithread like threading, I guess that is irelevant at the parrot level. Are you going to have one virtual cpu per thread with it's own set of registers or are you going to context switch the virtual cpu? What we're going to do is fire up a new interpreter for each thread. (We may have a pool of prebuilt interpreters hanging around for this eventuality) Threading *is* essential at the parrot level, and there are even a few (as yet undocumented) opcodes to deal with them, and some stuff that's an integral part of the variable vtable code to deal with it. Whether it's considered ithread-like or not's up in the air--it'll probably look a lot like a mix. I'm also seriously considering throwing *all* PerlIO code into separate threads (one per file) as an aid to asynchrony. Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Parrot multithreading?
AB == Arthur Bergman [EMAIL PROTECTED] writes: AB In an effort to rest my braine from a coredumping perl5 I started AB to think a bit on threading under parrot? While it has been AB decided that perl should be using ithread like threading, I guess AB that is irelevant at the parrot level. Are you going to have one AB virtual cpu per thread with it's own set of registers or are you AB going to context switch the virtual cpu? it is not irrelevent IMO. since each thread will have a private parrot interpreter, then parrot must minimize any globals so it can be almost all stack based. this means the parrot control structure must be malloc'd and only one pointer to it must be in some sort of global space (for thread management). this structure will manage the PC, the stacks, thread global vars, memory management (with or without gc?), etc. AB If it was one virtual cpu per thread then one would just create a AB new virtual cpu and feed it the bytecode stream? that is the idea as i have understood it. AB Is there anything I could help with regarding this? i think we need to design the (async) i/o and event subsystems either before or in parallel to the thread subsystem. they will all be coupled in various ways and it is better to do all the design first so you don't have awkward interfaces later. uri -- Uri Guttman - [EMAIL PROTECTED] -- http://www.sysarch.com SYStems ARCHitecture and Stem Development -- http://www.stemsystems.com Search or Offer Perl Jobs -- http://jobs.perl.org
Re: Parrot multithreading?
DS == Dan Sugalski [EMAIL PROTECTED] writes: DS I'm also seriously considering throwing *all* PerlIO code into separate DS threads (one per file) as an aid to asynchrony. but that will be hard to support on systems without threads. i still have that internals async i/o idea floating in my numb skull. it is an api that would look async on all platforms and will use the kernel async file i/o if possible. it could be made thread specific easily as my idea was that the event system was also thread specific. as i just got my home boxes reorganized and my wife is actually getting independent (drives herself now) from her broken leg, i will have some more time to burn here. uri -- Uri Guttman - [EMAIL PROTECTED] -- http://www.sysarch.com SYStems ARCHitecture and Stem Development -- http://www.stemsystems.com Search or Offer Perl Jobs -- http://jobs.perl.org
RE: Parrot multithreading?
DS I'm also seriously considering throwing *all* PerlIO code into separate DS threads (one per file) as an aid to asynchrony. but that will be hard to support on systems without threads. i still have that internals async i/o idea floating in my numb skull. it is an api that would look async on all platforms and will use the kernel async file i/o if possible. it could be made thread specific easily as my idea was that the event system was also thread specific. I think we should have some thread abstraction layer instead of throwing PerlIO into threads. The thread abstraction layer can use either native thread package (blocking io), or implement user level thread package with either non-blocking io or async io. The internal io should be sync instead of async. async is normally slower than sync (most of unix don't have real async io), and thread is cheap. Hong
Re: Parrot multithreading?
On Thu, Sep 20, 2001 at 12:33:54PM -0700, Hong Zhang wrote: DS I'm also seriously considering throwing *all* PerlIO code into separate DS threads (one per file) as an aid to asynchrony. but that will be hard to support on systems without threads. i still have that internals async i/o idea floating in my numb skull. it is an api that would look async on all platforms and will use the kernel async file i/o if possible. it could be made thread specific easily as my idea was that the event system was also thread specific. I think we should have some thread abstraction layer instead of throwing PerlIO into threads. The thread abstraction layer can use either native thread package (blocking io), or implement user level thread package with either non-blocking io or async io. The internal io should be sync instead of async. async is normally slower than sync (most of unix don't have real async io), and thread is cheap. I agree. Threads, at least in spirit, provide a cleaner interface to threading and asynchronous I/O than user level callbacks. There's nothing stopping a compiler from generating event driven code out of procedural, perhaps even threaded code. Consider this: sub read_console { print while (); } sub read_log { print while (LOG); } Thread-new( \read_console ); Thread-new( \read_log ); sleep 1 while threads_active(); exit 0; A compiler can either generate threaded code that's pretty close to the original source, or it can generate asynchronous callbacks at the bytecode level. The same source code could compile and run on systems that support asynchronous I/O, threads, or both. Here's some parrot assembly that may or may not be legal at the moment. It shows what a compiler might do with the threaded source code on a system that only supported asynchronous I/O. read_console_entry: find_global P1, STDIN, main set I1, read_console_got_line jsr set_input_callback return read_console_got_line: # Assumes the AIO engine sets S1 with a read line. printS1 return read_log_entry: find_global P1, LOG, main set I1, read_log_got_line jsr set_input_callback return read_log_got_line: # Assumes the AIO engine sets S1 with a read line. printS1 return main: set I1, read_console_entry jsr thread_new set I1, read_log_entry jsr thread_new main_timer_loop: set I1, main_timer_done set I2, 1 jsr set_timer return main_timer_done: jsr threads_active ne I1, 0, main_timer_loop end __END__ -- Rocco Caputo / [EMAIL PROTECTED] / poe.eekeek.org / poe.sourceforge.net
Re: Parrot multithreading?
Arthur Bergman wrote: In an effort to rest my braine from a coredumping perl5 I started to think a bit on threading under parrot? While it has been decided that perl should be using ithread like threading, I guess that is irelevant at the parrot level. Are you going to have one virtual cpu per thread with it's own set of registers or are you going to context switch the virtual cpu? If it was one virtual cpu per thread then one would just create a new virtual cpu and feed it the bytecode stream? Is there anything I could help with regarding this? Arthur The context is almost identical to that of Perl5's MULTIPLICITY which passes the perl-interpreter to each op-code. Thus there is inherent support for multiple ithread-streams. In the main-loop (between each invoked op-code) there is an event-checker (or was in older versions at any rate). It doesn't do anything yet, but it would make sence to assume that this is where context-switches would occur, which would simply involve swapping out the current pointer to the perl-context; A trivial matter. The easiest threading model I can think of would be to have a global var called next_interpreter which is always loaded in the do-loop. An asynchronous timer (or event) could cause the value of next_interpreter to be swapped. This way no schedule function need be checked on each operation. The cost is that of an extra indirection once per op-code. True MT code simply has each thread use it's own local interpreter instance. MT-code is problematic with non MT-safe extensions (since you can't enforce that). In iThread, you don't have a problem with atomic operations, but you can't take advantage of multiple CPUs nor can you garuntee prevention of IO-blocking (though you can get sneaky with UNIX-select). -Michael
Re: Parrot multithreading?
What we're going to do is fire up a new interpreter for each thread. (We may have a pool of prebuilt interpreters hanging around for this eventuality) Threading *is* essential at the parrot level, and there are even a few (as yet undocumented) opcodes to deal with them, and some stuff that's an integral part of the variable vtable code to deal with it. Whether it's considered ithread-like or not's up in the air--it'll probably look a lot like a mix. I'm also seriously considering throwing *all* PerlIO code into separate threads (one per file) as an aid to asynchrony. Just remember the cost in context-switching, plus the lack of scalability as the number of file-handles increases. Linux thread-context-switches are relatively brutal compared to say Solaris. Additionally you're consuming a new stack area for each file-handle. That's lots of overhead. There are bound to be semi-portable methods of non-blocking IO. UNIX-select has to have an equiv on NT. Granted it's a lot more complicated. Basically you could have IO ops trigger an event-based iThread swap, which causes select to be invoked. I've always thought this was the most efficient model for single-CPU machines. The biggest problem was always segmenting one's code into call-backs. Well, with op-codes, we have a natural division. We have a tight inner loop that occasionally hits a dispatcher on a complexity level similar to a GUI. You're much better prone to handle event-based operations (which means higher level languages can be built atop such a parrot-design). Food for thought. -Michael
Re: Parrot multithreading?
On Thu, Sep 20, 2001 at 04:13:48PM -0400, Michael L Maraist wrote: What we're going to do is fire up a new interpreter for each thread. (We may have a pool of prebuilt interpreters hanging around for this eventuality) Threading *is* essential at the parrot level, and there are even a few (as yet undocumented) opcodes to deal with them, and some stuff that's an integral part of the variable vtable code to deal with it. Whether it's considered ithread-like or not's up in the air--it'll probably look a lot like a mix. I'm also seriously considering throwing *all* PerlIO code into separate threads (one per file) as an aid to asynchrony. Just remember the cost in context-switching, plus the lack of scalability as the number of file-handles increases. Linux thread-context-switches are relatively brutal compared to say Solaris. Additionally you're consuming a new stack area for each file-handle. That's lots of overhead. One idea I haven't seen mentioned is have a fixed number of system threads to service a potentially larger pool of parrot interpreters. Essentially, physical threads become execution pipelines for the virtual machine. The limit on system threads can be tuned to optimally spread execution across available CPUs. It could be as small as 1 on single-processor systems that don't switch thread contexts well. -- Rocco Caputo / [EMAIL PROTECTED] / poe.perl.org / poe.sourceforge.net
RE: Parrot multithreading?
At 12:33 PM 9/20/2001 -0700, Hong Zhang wrote: DS I'm also seriously considering throwing *all* PerlIO code into separate DS threads (one per file) as an aid to asynchrony. but that will be hard to support on systems without threads. i still have that internals async i/o idea floating in my numb skull. it is an api that would look async on all platforms and will use the kernel async file i/o if possible. it could be made thread specific easily as my idea was that the event system was also thread specific. I think we should have some thread abstraction layer instead of throwing PerlIO into threads. The thread abstraction layer can use either native thread package (blocking io), or implement user level thread package with either non-blocking io or async io. I did say I was seriously considering it, not that I was going to do it. We may well just throw the PerlIO stuff (at least anything with a filter) into separate interpreters rather than separate threads. We'll see. The internal io should be sync instead of async. Nope. Internal I/O, at least as the interpreter will see it is async. You can build sync from async, it's a big pain to build async from sync. Doesn't mean we actually get asynchrony, just that we can. async is normally slower than sync (most of unix don't have real async io), and thread is cheap. Just because some systems have a really pathetic I/O system doesn't mean we should penalize those that don't... Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Parrot multithreading?
At 04:36 PM 9/20/2001 -0400, Rocco Caputo wrote: On Thu, Sep 20, 2001 at 04:13:48PM -0400, Michael L Maraist wrote: What we're going to do is fire up a new interpreter for each thread. (We may have a pool of prebuilt interpreters hanging around for this eventuality) Threading *is* essential at the parrot level, and there are even a few (as yet undocumented) opcodes to deal with them, and some stuff that's an integral part of the variable vtable code to deal with it. Whether it's considered ithread-like or not's up in the air--it'll probably look a lot like a mix. I'm also seriously considering throwing *all* PerlIO code into separate threads (one per file) as an aid to asynchrony. Just remember the cost in context-switching, plus the lack of scalability as the number of file-handles increases. Linux thread-context-switches are relatively brutal compared to say Solaris. Additionally you're consuming a new stack area for each file-handle. That's lots of overhead. One idea I haven't seen mentioned is have a fixed number of system threads to service a potentially larger pool of parrot interpreters. Essentially, physical threads become execution pipelines for the virtual machine. The limit on system threads can be tuned to optimally spread execution across available CPUs. It could be as small as 1 on single-processor systems that don't switch thread contexts well. That adds a level of complexity to things that I'd as soon avoid. On the other hand there's no reason we can't add it in later. Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Parrot multithreading?
At 01:53 PM 9/20/2001 -0700, Damien Neil wrote: On Thu, Sep 20, 2001 at 04:38:57PM -0400, Dan Sugalski wrote: Nope. Internal I/O, at least as the interpreter will see it is async. You can build sync from async, it's a big pain to build async from sync. Doesn't mean we actually get asynchrony, just that we can. For clarification: do you mean async I/O, or non-blocking I/O? Async. When the interpreter issues a read, for example, it won't assume the read completes immediately. Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
RE: Parrot multithreading?
Nope. Internal I/O, at least as the interpreter will see it is async. You can build sync from async, it's a big pain to build async from sync. Doesn't mean we actually get asynchrony, just that we can. It is trivial to build async from sync, just using thread. Most Unix async are built this way, using either user level thread or kernel level thread. Win32 has really async io implementation, but it does not interact well with sync io. Just because some systems have a really pathetic I/O system doesn't mean we should penalize those that don't... Implement sync on top of async is also slower. I bet most people will use sync io, not async one. There is no need to build async io from sync, the async can be provided using separate module. It is not about some systems, it is about most systems. Very few systems have high performance async io implementation. And the semantics is not very portable. I am not sure if interpreter has to choose one over the other. The interpreter could support both interface, and use as needed. Hong
Re: Parrot multithreading?
DN == Damien Neil [EMAIL PROTECTED] writes: DN On Thu, Sep 20, 2001 at 04:57:44PM -0400, Dan Sugalski wrote: For clarification: do you mean async I/O, or non-blocking I/O? Async. When the interpreter issues a read, for example, it won't assume the read completes immediately. DN That sounds like what I would call non-blocking I/O. Async I/O DN would involve syscalls like aio_read(). you can't do non-blocking i/o on files without aio_read type calls. but what dan is saying is that the api the interpreter uses internally will be an async one. it will either use native/POSIX aio calls or simulate that with sync calls and callbacks or possibly with threads. DN I'm being a bit pedantic here because I've been involved in heated DN debates in the past, which were resolved when the two sides realized DN that they were using different definitions of async I/O. : pipe, socket and char device async i/o is different from file async i/o. with pipes you are told when your request will work and then you make it. with files you make the request and then get told when it was done. both use callbacks and can be integrated under one async api. this api is what parrot will see and a sync api will be layered on top of this. the async i/o will be tied to the event system for timeouts and safe signals and such. uri -- Uri Guttman - [EMAIL PROTECTED] -- http://www.sysarch.com SYStems ARCHitecture and Stem Development -- http://www.stemsystems.com Search or Offer Perl Jobs -- http://jobs.perl.org
Re: Parrot multithreading?
At 02:04 PM 9/20/2001 -0700, Damien Neil wrote: On Thu, Sep 20, 2001 at 04:57:44PM -0400, Dan Sugalski wrote: For clarification: do you mean async I/O, or non-blocking I/O? Async. When the interpreter issues a read, for example, it won't assume the read completes immediately. That sounds like what I would call non-blocking I/O. Async I/O would involve syscalls like aio_read(). Might sound that way, but it isn't. What I'm talking about is something like: READ S3, P1, I0 X: SLEEP 3 EQ I0, 0, X PRINT S3 Where we issue the read on the filehandle in P1, telling it to store the results in S3, and put the completion status in I0. The sleep will presumably be replaced by code that actually does something, and we wait as long as the completion register says we're not done. Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Parrot multithreading?
DS == Dan Sugalski [EMAIL PROTECTED] writes: DS Might sound that way, but it isn't. What I'm talking about is DS something like: DS READ S3, P1, I0 DS X: SLEEP 3 DS EQ I0, 0, X DS PRINT S3 DS Where we issue the read on the filehandle in P1, telling it to DS store the results in S3, and put the completion status in I0. The DS sleep will presumably be replaced by code that actually does DS something, and we wait as long as the completion register says DS we're not done. and internally tha READ op will do an aio_read if it is supported on this platform. the sleep op is like wait in pdp-11 assembler. there you could wait for interrupts to wake you up. that sleep op needs to do a blocking operation like poll/select so it can release the cpu for other threads/processes. it will be woken up by a signal that the file async i/o is done a variation is to have a WAIT op which waits for a particular io handle to be done. it also will do some blocking select/poll call and let itself be woken up as above. but it will check for its i/o being done and go back to blocking sleep if it is not completed. so you can issue an async i/o request anytime and sync up with it (with WAIT) later when you want the data. this model was in RT-11 30 years ago and it works well. you can have async and sync i/o with a simple set of ops, READ, WRITE and WAIT. we could also have a WAIT with a wild card arg too. it waits for any completion of i/o and then other parrot code must check for what has completed and deal with it. uri -- Uri Guttman - [EMAIL PROTECTED] -- http://www.sysarch.com SYStems ARCHitecture and Stem Development -- http://www.stemsystems.com Search or Offer Perl Jobs -- http://jobs.perl.org