Efficient thread-local shared variables

Klaus D. Witzel klaus.witzel at cobss.com
Tue Oct 24 10:13:19 UTC 2006


Hi Reinout,

I have almost the same implementation for two purposes:

- the slots of (clones of) a prototype
- the roles of a player

The setters/getters are made from template methods which share a new  
literal variable (an other concept is used for slots).

When you say that insertion/removal is slow, what do you compare that to:  
add/remove to/from an OrderedCollection, or just compared to set/get?

Have you considered alternatives, any comparisions or ideas that you can  
share?

/Klaus

On Tue, 24 Oct 2006 10:02:47 +0200, Reinout Heeck wrote:

>>
>> 2) Use message lookup, e.g., send a message. This is simple to describe  
>> but not necessarily simple to implement correctly. Here is how the  
>> simulation would look like:
>>
>
>
> I have experimented with this in VisualWorks (to implement a new  
> namespace system, not per-process pools) with great results regarding  
> speed. The two concepts I needed (stolen from Forth) where Vocabulary (a  
> Dictionary) and SearchOrder (a stack of those dictionaries). My  
> breakthrough came when I realized that my search rules in a SearchOrder  
> where the same as those the VM uses when doing method lookup.
>
> So I implemented a Vocabulary 'instance' as a pair of a anonymous class  
> and a singleton instance of that class, lookup is done by sending a  
> message to the instance (fast), insertion/removal is done by  
> adding/removing methods in the class (slow).
> The methods are very simple: they return their first literal, where the  
> literal slot holds the value to be returned from the dictionary for the  
> key assigned as that method's selector.
>
>> ProtoObject>>lookup: sharedBinding
>>     "Look up the value of the given shared binding in the currently  
>> executing process."
>>     ^[Processor activeProcess scope perform: sharedBinding key]
>>        on: MessageNotUnderstood do:[:ex| ex return: nil].
>
>
> In my scheme you can get rid of the cost of this exception handler by  
> reimplementing #doesNotUnderstand: on the anonymous class so it raises a  
> KeyNotFound error (or returns nil as your snippet suggests). In VW  
> #doesNotUnderstand: is fully supported by the VM optimizations (ICs,  
> PICs, hoisting etc..) making lookup misses a fast path, I don't know  
> whether Squeak does the same in the case of #doesNotUnderstand:, you may  
> want to measure that.
>
> ProtoObject>>lookup: sharedBinding
> 	^Processor activeScope perform: sharedBinding key
>
>
>
>> One problem here is that the key needs to be unique within all possible  
>> keys which is a problem if there is a name conflict. This can be  
>> resolved by implicitly prefixing names with the place where they are  
>> defined so it's not such big of a deal conceptually but practically the  
>> impact of that change might be more visible.
>
>
> This is where SearchOrder enters the picture (assuming your conflicts  
> arise because you don't model scoping).
> SearchOrder is implemented by chaining Vocabularies through the  
> #superclass attribute of the anonymous class. The VM will run through  
> this chain when a miss happens on the first Vocabulary and the nice  
> thing is that it will probably optimize future lookup of this key (by  
> hoisting).
>
> Implementing scoping is obviously more involved since you need to know  
> /where from/ the lookup is performed.
>
> Naively:
> 	^(Procesor activeScopeFor: self class) perform: sharedBinding key
>
> Perhaps you can make gains by cashing the per-process SearchOrders  
> belonging only to this calling scope in the sharedBinding?
>
> 	^(sharedBinding scopeFor: Processor activeProcess) perform:  
> sharedBinding key
> 	"we lost the 'self class' because the binding already 'knows' that"
>
> That last snippet clearly wants to be implemented on sharedBinding  
> instead of ProtoObject  ;-)
>
>>
>> The other problem is that the scope object needs to hold all the  
>> objects which means quite a number of them. OTOH, one could argue that  
>> in many ways "Smalltalk" is just an object with a few thousand iVars so  
>> having a class representing the namespace defined by Smalltalk may be  
>> quite reasonable.
>
> In my scheme Smalltalk would be modeled by an anonymous class that  
> implements thousands of methods, each with one literal, no ivars are  
> involved.
> So you are limited by the maximum number of methods a class may  
> implement. I guess that is infinite for our purposes, but if Squeak does  
> have an upper limit on the number of methods per class you can work  
> around that by splitting the oversized Vocabularies into multiple  
> Vocabularies that are placed adjacent in the SearchOrder.
>
>
>
>
>
> I don't actively follow this list, so please CC reinz at desk.org if you  
> have any questions.
>
> Furthermore I'm vain, so please credit me if you decide to run with this  
> :-)
>
> R
> -
>
>
>
>
>
>





More information about the Squeak-dev mailing list