Jump to page: 1 27  
Page
Thread overview
Low-Lock Singletons In D
May 06, 2013
dsimcha
May 06, 2013
Joshua Niehus
May 06, 2013
Mehrdad
May 06, 2013
Mehrdad
May 06, 2013
Sergei Nosov
May 06, 2013
Mehrdad
May 06, 2013
Dmitry Olshansky
May 06, 2013
Mehrdad
May 06, 2013
Mehrdad
May 06, 2013
deadalnix
May 06, 2013
Mehrdad
May 06, 2013
Dmitry Olshansky
May 06, 2013
Mehrdad
May 06, 2013
David Nadlinger
May 07, 2013
Mehrdad
May 06, 2013
Dmitry Olshansky
May 07, 2013
Mehrdad
May 07, 2013
Dmitry Olshansky
May 06, 2013
Walter Bright
May 06, 2013
Mehrdad
May 07, 2013
Mehrdad
May 07, 2013
deadalnix
May 07, 2013
Dmitry Olshansky
May 08, 2013
deadalnix
May 07, 2013
Mehrdad
May 07, 2013
Mehrdad
May 07, 2013
Brad Roberts
May 07, 2013
Walter Bright
May 07, 2013
Dmitry Olshansky
May 07, 2013
QAston
May 07, 2013
QAston
May 25, 2013
Mehrdad
May 07, 2013
Sean Kelly
May 07, 2013
David Nadlinger
May 06, 2013
Max Samukha
May 06, 2013
Walter Bright
May 24, 2013
Max Samukha
May 24, 2013
bearophile
May 24, 2013
Max Samukha
May 24, 2013
bearophile
May 24, 2013
Max Samukha
May 24, 2013
bearophile
May 24, 2013
deadalnix
May 06, 2013
Idan Arye
May 06, 2013
Andrej Mitrovic
May 06, 2013
Diggory
May 06, 2013
Andrej Mitrovic
May 06, 2013
On the advice of Walter and Andrei, I've written a blog article about the low-lock Singleton pattern in D.  This is a previously obscure pattern that uses thread-local storage to make Singletons both thread-safe and efficient and was independently invented by at least me and Alexander Terekhov, an IBM researcher.  However, D's first-class treatment of thread-local storage means the time has come to move it out of obscurity and possibly make it the standard way to do Singletons.

Article:
http://davesdprogramming.wordpress.com/2013/05/06/low-lock-singletons/

Reddit:
http://www.reddit.com/r/programming/comments/1droaa/lowlock_singletons_in_d_the_singleton_pattern/
May 06, 2013
On Monday, 6 May 2013 at 02:35:33 UTC, dsimcha wrote:
> Article:
> http://davesdprogramming.wordpress.com/2013/05/06/low-lock-singletons/
>
> Reddit:
> http://www.reddit.com/r/programming/comments/1droaa/lowlock_singletons_in_d_the_singleton_pattern/

Excellent talk at the conf, solid blog: +1 and 1
May 06, 2013
On 5/5/13 10:35 PM, dsimcha wrote:
> On the advice of Walter and Andrei, I've written a blog article about
> the low-lock Singleton pattern in D. This is a previously obscure
> pattern that uses thread-local storage to make Singletons both
> thread-safe and efficient and was independently invented by at least me
> and Alexander Terekhov, an IBM researcher. However, D's first-class
> treatment of thread-local storage means the time has come to move it out
> of obscurity and possibly make it the standard way to do Singletons.
>
> Article:
> http://davesdprogramming.wordpress.com/2013/05/06/low-lock-singletons/
>
> Reddit:
> http://www.reddit.com/r/programming/comments/1droaa/lowlock_singletons_in_d_the_singleton_pattern/

The reddit post is in need for upvotes to make it on the /r/programming front page. I think posting time wasn't the best: Saturday is the worst day to post anything (http://www.slideshare.net/babasave/the-hidden-secrets-of-successful-reddit-posts).

Anyhow, I've also posted to https://news.ycombinator.com/item?id=5660897

Vote up!


Andrei


May 06, 2013
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>();

		public T Get()
		{
			lock (this)
			{
				_static = new ActualValue<T>();
			}
			// 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
	}
}
May 06, 2013
On Monday, 6 May 2013 at 09:06:55 UTC, Mehrdad wrote:
> lock (this)
> {
> 	_static = new ActualValue<T>();
> }

Oops I forgot the null check inside, don't forget that.
May 06, 2013
On Monday, 6 May 2013 at 09:11:00 UTC, Mehrdad wrote:
> On Monday, 6 May 2013 at 09:06:55 UTC, Mehrdad wrote:
>> lock (this)
>> {
>> 	_static = new ActualValue<T>();
>> }
>
> Oops I forgot the null check inside, don't forget that.

All that double-checking stuff is trying to avoid calling "lock" for entire Get function body. Your solution does exactly that. So it's no good.
May 06, 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
May 06, 2013
On 5/6/2013 2:06 AM, Mehrdad wrote:
> 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.

I did that too. It's trickier than it appears.

May 06, 2013
On Monday, 6 May 2013 at 09:30:24 UTC, Sergei Nosov wrote:
> On Monday, 6 May 2013 at 09:11:00 UTC, Mehrdad wrote:
>> On Monday, 6 May 2013 at 09:06:55 UTC, Mehrdad wrote:
>>> lock (this)
>>> {
>>> 	_static = new ActualValue<T>();
>>> }
>>
>> Oops I forgot the null check inside, don't forget that.
>
> All that double-checking stuff is trying to avoid calling "lock" for entire Get function body. Your solution does exactly that. So it's no good.



There are _two_ Get() functions. Only one of them calls lock(); once the field is initialized, that Get() is no longer called, and the other one is called instead.

Unless I'm missing something?
May 06, 2013
On Monday, 6 May 2013 at 09:35:59 UTC, Dmitry Olshansky wrote:
> 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


Isn't that why I wrote this?

>>             // Insert memory barrier if you'd like
« First   ‹ Prev
1 2 3 4 5 6 7