Igor, why don't you add your ideas to http://wiki.squeak.org/squeak/6012. . . .
----- Original Message ---- From: Igor Stasenko siguctua@gmail.com
On 30/10/2007, Rob Withers reefedjib@yahoo.com wrote:
It seems to me that you are building event-loops in the VM. Consider anObject that is sent a msg on thread 1, so he is assigned to thread 1 and you start processing it with thread 1. In the meantime, 3 msgs are sent to this object on threads 2, 3, and 4. Each message send is scheduled for processing by thread 1, when it becomes available. There is your event-loop.
Yes, exactly. I'm still unsure if it really needed for all objects in system. For instance, the true/false/nil object are just singletons without any internal state. Thus scheduling them into single thread of execution can be simply omitted.
The same goes for SmallIntegers, which while not singletons, are not mutable. Perhaps Characters are also candidates for this. These are PassByConstruction objects, which means they are always local. PassByCopy is another type of PassByConstruction, where a copy is marshalled to the other side.
The other thing which bothers me is a reflection. Should we expose a properties of native threads at language side (for using/showing them in debugger)? Or how well new contexts will deal with continuations, which is used in seaside..
I think each process should know which thread id it is running in. In my model, the process stays with the thread, while in yours I am not sure. A message to a VatRef to an object in a different Vat, would be sent asynchronously and scheduled in the other Vat for it's thread to process.
BTW, in another email you asked about how passing a ref between Vats (Islands) guaranteed that all msgs to it would go to the home Vat. The answer is that a ref to a Vat local object, being passed as an arg to a msg send to a VatRef to an object in a different Vat, would be translated into a VatRef back to the origin Vat when the MsgSend marshalled it's arguments to the 2nd Vat. No ref with direct memory access would ever be allowed to be passed to another Vat.
But the primitive may have internal state that can't be shared.
I know, but i'm talking about basic primitives which used most frequently and operating only with object memory. Such primitives usually don't have any internal state, or using an interpreter state.
Ok, so from the link above, the ProtectedPrimitives would not always be protected.
All other primitives which have internal state should be reviewed. And at first stages we could add support for scheduling all these 'old' primitives into single 'main' thread. So they will work as in current VM not knowing that VM is actually multithreaded.
I was thinking we mutex protect them, but still allow different threads to use them.
I'd like to hear more critics about such model :) If it proves to be viable and much or less easily doable (comparing to other models) then i could start working on it :)
Go for it!!
cheers, Rob
On 30/10/2007, Rob Withers reefedjib@yahoo.com wrote:
Igor, why don't you add your ideas to http://wiki.squeak.org/squeak/6012. . . .
I think i can help with: # Understand CCodeGenerator and TParseNode hierarchy.
Lately i did conversion of parse tree into lambda message sends. Then by using transformers(substitution/replacement) its easy to convert them into bytecodes, C/C++ source or to Exupery intermediate representation, since lambdas are uniform representation of algorithm. I don't know how much such abstraction could ease development. Actually my original idea was to represent compiled methods not in bytecode but in lambdas. Yes, bytecodes can be viewed as short representation of lambda-functions, but the difference is, that they are not real objects. Lambdas are best fit for method inlining, since substitution of free variables can be done relatively easily at low-level (VM).
----- Original Message ---- From: Igor Stasenko siguctua@gmail.com
On 30/10/2007, Rob Withers reefedjib@yahoo.com wrote:
It seems to me that you are building event-loops in the VM. Consider anObject that is sent a msg on thread 1, so he is assigned to thread 1
and
you start processing it with thread 1. In the meantime, 3 msgs are sent
to
this object on threads 2, 3, and 4. Each message send is scheduled for processing by thread 1, when it becomes available. There is your event-loop.
Yes, exactly. I'm still unsure if it really needed for all objects in system. For instance, the true/false/nil object are just singletons without any internal state. Thus scheduling them into single thread of execution can be simply omitted.
The same goes for SmallIntegers, which while not singletons, are not mutable. Perhaps Characters are also candidates for this.
I think this can be simply done by testing , if given object is non-indexable and having ivar count =0, or its having a readonly flag set.
These are PassByConstruction objects, which means they are always local. PassByCopy is another type of PassByConstruction, where a copy is marshalled to the other side.
Hmm i can't follow you here. Could you elaborate?
The other thing which bothers me is a reflection. Should we expose a properties of native threads at language side (for using/showing them in debugger)? Or how well new contexts will deal with continuations, which is used in seaside..
I think each process should know which thread id it is running in. In my model, the process stays with the thread, while in yours I am not sure. A message to a VatRef to an object in a different Vat, would be sent asynchronously and scheduled in the other Vat for it's thread to process.
Yes, i don't like to bind the language side Process to particular native thread. Simply because of scheduling/preemption issues. Trying to do nice scheduling with different native thread issues under different platforms/OSes could be a quite messy. We are really don't need to have more than a fixed number of threads in VM (one for each core, and maybe 1 more for GC).
BTW, in another email you asked about how passing a ref between Vats (Islands) guaranteed that all msgs to it would go to the home Vat. The answer is that a ref to a Vat local object, being passed as an arg to a msg send to a VatRef to an object in a different Vat, would be translated into a VatRef back to the origin Vat when the MsgSend marshalled it's arguments to the 2nd Vat. No ref with direct memory access would ever be allowed to be passed to another Vat.
But the primitive may have internal state that can't be shared.
I know, but i'm talking about basic primitives which used most frequently and operating only with object memory. Such primitives usually don't have any internal state, or using an interpreter state.
Ok, so from the link above, the ProtectedPrimitives would not always be protected.
All other primitives which have internal state should be reviewed. And at first stages we could add support for scheduling all these 'old' primitives into single 'main' thread. So they will work as in current VM not knowing that VM is actually multithreaded.
I was thinking we mutex protect them, but still allow different threads to use them.
I'd like to hear more critics about such model :) If it proves to be viable and much or less easily doable (comparing to other models) then i could start working on it :)
Go for it!!
cheers, Rob
On 10/30/07, Igor Stasenko siguctua@gmail.com wrote:
We are really don't need to have more than a fixed number of threads in VM (one for each core, and maybe 1 more for GC).
I'm totally on board the idea of native threads being internal to the VM, and client code not being aware. But my plan is to provide a way change how many threads that is, as 1 per CPU is not always optimal.
When Erlang first did this, their approach was making a schedular 1-to-1 with a native thread. They seem to hit max performance at about 4 native threads per CPU core (if you want the reference I will try to dig it up, but I'm sure if your google-fu is strong, you should find it fairly quick).
On 30/10/2007, Jason Johnson jason.johnson.081@gmail.com wrote:
On 10/30/07, Igor Stasenko siguctua@gmail.com wrote:
We are really don't need to have more than a fixed number of threads in VM (one for each core, and maybe 1 more for GC).
I'm totally on board the idea of native threads being internal to the VM, and client code not being aware. But my plan is to provide a way change how many threads that is, as 1 per CPU is not always optimal.
I agree on that. But such details can be discovered later.
When Erlang first did this, their approach was making a schedular 1-to-1 with a native thread. They seem to hit max performance at about 4 native threads per CPU core (if you want the reference I will try to dig it up, but I'm sure if your google-fu is strong, you should find it fairly quick).
Most of reasons why CPU not utilized at 100% is using a blocking I/O calls. Then a simplest solution to not use them and instead of blowing up the number of threads use asynchronous I/O . Most major platforms support asynchronous I/O and there are many libraries which support async data handling almost in each area we need for. We just need to build on top of them.
On 10/30/07, Igor Stasenko siguctua@gmail.com wrote:
Most of reasons why CPU not utilized at 100% is using a blocking I/O calls. Then a simplest solution to not use them and instead of blowing up the number of threads use asynchronous I/O . Most major platforms support asynchronous I/O and there are many libraries which support async data handling almost in each area we need for. We just need to build on top of them.
Good point. How many kinds of I/O in Squeak is currently blocking? I think I heard networking blocks, what about disk?
On 31/10/2007, Jason Johnson jason.johnson.081@gmail.com wrote:
On 10/30/07, Igor Stasenko siguctua@gmail.com wrote:
Most of reasons why CPU not utilized at 100% is using a blocking I/O calls. Then a simplest solution to not use them and instead of blowing up the number of threads use asynchronous I/O . Most major platforms support asynchronous I/O and there are many libraries which support async data handling almost in each area we need for. We just need to build on top of them.
Good point. How many kinds of I/O in Squeak is currently blocking? I think I heard networking blocks, what about disk?
All socket/file IO primitives using blocking calls. To what i see, there is only one set of async primitives - AsyncFilePlugin. But i'm not sure if it used at first place (i.e. replaces a FilePlugin). I think Andreas could answer on this more precisely.
If this is the case, then I wonder how far we could get by just making all I/O async.
On 10/31/07, Igor Stasenko siguctua@gmail.com wrote:
On 31/10/2007, Jason Johnson jason.johnson.081@gmail.com wrote:
On 10/30/07, Igor Stasenko siguctua@gmail.com wrote:
Most of reasons why CPU not utilized at 100% is using a blocking I/O calls. Then a simplest solution to not use them and instead of blowing up the number of threads use asynchronous I/O . Most major platforms support asynchronous I/O and there are many libraries which support async data handling almost in each area we need for. We just need to build on top of them.
Good point. How many kinds of I/O in Squeak is currently blocking? I think I heard networking blocks, what about disk?
All socket/file IO primitives using blocking calls. To what i see, there is only one set of async primitives - AsyncFilePlugin. But i'm not sure if it used at first place (i.e. replaces a FilePlugin). I think Andreas could answer on this more precisely.
-- Best regards, Igor Stasenko AKA sig.
On Wed, Oct 31, 2007 at 03:44:10PM +0200, Igor Stasenko wrote:
All socket/file IO primitives using blocking calls. To what i see, there is only one set of async primitives - AsyncFilePlugin. But i'm not sure if it used at first place (i.e. replaces a FilePlugin). I think Andreas could answer on this more precisely.
The SocketPlugin implements asynchronous I/O for all platforms, so socket operations are nonblocking.
OSProcessPlugin also provides nonblocking I/O, but only on unix/mac platforms at the moment. AioPlugin implements the aio interface to enable notification of a Squeak semaphore on data availability. These are used in OSProcess and CommandShell for nonblocking I/O on files and pipes, especially for interprocess communication using OS pipes.
Dave
squeak-dev@lists.squeakfoundation.org