Low-Lock Singletons In D

Dmitry Olshansky dmitry.olsh at gmail.com
Mon May 6 02:35:51 PDT 2013


06-May-2013 13:06, Mehrdad пишет:
> On Monday, 6 May 2013 at 02:35:33 UTC, dsimcha wrote:
>> that uses thread-local storage
>> On DMD the overhead of TLS vs. unsafe is noticeable but small. In both
>> cases it pales in comparison to the overhead of synchronizing on every
>> call to get().
>
>
> Hmm...
>
> So I just invented another method right now in like 10 minutes, which
> can completely avoid TLS altogether, and which I think might end up
> being faster.
>
> Basically, my idea is that since modern CPUs (x86) are great at
> predicting predictable virtual calls, you can use that to your advantage
> as shown below.
>
>
> The code below is C#, but easy enough to turn into D... I don't have the
> time to do it at the moment but if you're interested give it a try and
> see how it compares to TLS:
>
>
> class Program
> {
>      private interface IValue<T>
>      {
>          T Get();
>      }
>
>      private class ActualValue<T> : IValue<T>
>      {
>          private T value;
>          public T Get() { return this.value; }
>      }
>
>      private class NullValue<T> : IValue<T>
>      {
>          // This field is initialized on startup
>          public static IValue<T> _static = new NullValue<T>();

And that field is still shared... it doesn't matter if the null was 
replaced by NullValue and an if-branch with indirect call.

You have to read a field to know what to do next, and the other 
processor may as well write to it.

>
>          public T Get()
>          {
>              lock (this)
>              {
			if(_static != null)
>                  _static = new ActualValue<T>();

Who told you that the processor will immediately see the fully 
constructed value of ActualValue upon assignment? Barriers and other 
minor forms of black magic are still required on each access (e.g. 
atomic reads and atomic write) which isn't the case with TLS flag as 
discussed.

>              }
>              // Insert memory barrier if you'd like
>              return _static.Get();
>          }
>      }
>
>      public static object Static
>      { get { return NullValue<object>._static.Get(); } }
>
>
>      static void Main(string[] args)
>      {
>          var a = Static;  // initializes on first use
>          var b = Static;  // doesn't initialize anymore
>      }
> }


-- 
Dmitry Olshansky


More information about the Digitalmars-d mailing list