Jump to page: 1 2
Thread overview
druntime thread_needLock()
Dec 06, 2008
dsimcha
Dec 06, 2008
Sean Kelly
Dec 06, 2008
Fawzi Mohamed
Dec 06, 2008
Fawzi Mohamed
Dec 06, 2008
Sean Kelly
Dec 06, 2008
Fawzi Mohamed
Dec 07, 2008
Sean Kelly
Dec 07, 2008
Fawzi Mohamed
Dec 07, 2008
Sean Kelly
Dec 07, 2008
Fawzi Mohamed
Dec 06, 2008
Leandro Lucarella
Dec 06, 2008
Fawzi Mohamed
Dec 06, 2008
Christopher Wright
Dec 06, 2008
Leandro Lucarella
Dec 07, 2008
Robert Fraser
Dec 07, 2008
Fawzi Mohamed
Dec 07, 2008
BCS
December 06, 2008
According to both the docs and my own experiments, thread_needLock() in core.thread returns a bool that depends on whether the current process has *ever* been multithreaded at *any* point in its execution.  In Phobos's GC (pre-druntime), a similar function existed, but it returned a bool based on whether more than 1 thread was *currently* running.  It seems to me that omitting locks should be safe if no more than 1 thread is currently running, even if more than 1 was running at some point in the past.  Why is druntime's thread_needLock() designed the way it is?
December 06, 2008
dsimcha wrote:
> According to both the docs and my own experiments, thread_needLock() in
> core.thread returns a bool that depends on whether the current process has
> *ever* been multithreaded at *any* point in its execution.  In Phobos's GC
> (pre-druntime), a similar function existed, but it returned a bool based on
> whether more than 1 thread was *currently* running.  It seems to me that
> omitting locks should be safe if no more than 1 thread is currently running,
> even if more than 1 was running at some point in the past.  Why is druntime's
> thread_needLock() designed the way it is?

Typically, the stores of a terminating thread are only guaranteed to be visible when join() returns for that thread... and then to the joining thread only.  While it's true that the stores will eventually be visible to all threads in a program, there's no easy way to figure out exactly when this is (the lock-free people would probably say you'd have to wait for a "quiescent state").  I also don't know of any apps that are multi threaded for a while and then later become single threaded, so the issue of performance loss seems like somewhat of a corner case.


Sean
December 06, 2008
On 2008-12-06 06:02:44 +0100, dsimcha <dsimcha@yahoo.com> said:

> According to both the docs and my own experiments, thread_needLock() in
> core.thread returns a bool that depends on whether the current process has
> *ever* been multithreaded at *any* point in its execution.  In Phobos's GC
> (pre-druntime), a similar function existed, but it returned a bool based on
> whether more than 1 thread was *currently* running.  It seems to me that
> omitting locks should be safe if no more than 1 thread is currently running,
> even if more than 1 was running at some point in the past.  Why is druntime's
> thread_needLock() designed the way it is?

Indeed I see no real reason not to keep a thread could that would be incremented before spawn or in thread_attach, and decremented at the end of thread_entryFunction and thread_detach.

Potentially one could think badly written code similar to this
 if (thread_needLock()) lock();
 if (thread_needLock()) unlock();
or initializations done unconditionally when the runtime becomes multithreaded,
but I found no issues like this in tangos runtime, thread_needLock is used only to then do synchronized(...){...}

So yes one could probably switch back to the old Phobos style.
I would guess that it is not really a common situation for a program to become single threaded again, though...

Fawzi

December 06, 2008
On 2008-12-06 08:33:40 +0100, Sean Kelly <sean@invisibleduck.org> said:

> dsimcha wrote:
>> According to both the docs and my own experiments, thread_needLock() in
>> core.thread returns a bool that depends on whether the current process has
>> *ever* been multithreaded at *any* point in its execution.  In Phobos's GC
>> (pre-druntime), a similar function existed, but it returned a bool based on
>> whether more than 1 thread was *currently* running.  It seems to me that
>> omitting locks should be safe if no more than 1 thread is currently running,
>> even if more than 1 was running at some point in the past.  Why is druntime's
>> thread_needLock() designed the way it is?
> 
> Typically, the stores of a terminating thread are only guaranteed to be visible when join() returns for that thread... and then to the joining thread only.  While it's true that the stores will eventually be visible to all threads in a program, there's no easy way to figure out exactly when this is (the lock-free people would probably say you'd have to wait for a "quiescent state").  I also don't know of any apps that are multi threaded for a while and then later become single threaded, so the issue of performance loss seems like somewhat of a corner case.
> 
> 
> Sean

ok so this is the reason, good to know...

Fawzi

December 06, 2008
On 2008-12-06 09:44:06 +0100, Fawzi Mohamed <fmohamed@mac.com> said:

> On 2008-12-06 08:33:40 +0100, Sean Kelly <sean@invisibleduck.org> said:
> 
>> dsimcha wrote:
>>> According to both the docs and my own experiments, thread_needLock() in
>>> core.thread returns a bool that depends on whether the current process has
>>> *ever* been multithreaded at *any* point in its execution.  In Phobos's GC
>>> (pre-druntime), a similar function existed, but it returned a bool based on
>>> whether more than 1 thread was *currently* running.  It seems to me that
>>> omitting locks should be safe if no more than 1 thread is currently running,
>>> even if more than 1 was running at some point in the past.  Why is druntime's
>>> thread_needLock() designed the way it is?
>> 
>> Typically, the stores of a terminating thread are only guaranteed to be visible when join() returns for that thread... and then to the joining thread only.  While it's true that the stores will eventually be visible to all threads in a program, there's no easy way to figure out exactly when this is (the lock-free people would probably say you'd have to wait for a "quiescent state").  I also don't know of any apps that are multi threaded for a while and then later become single threaded, so the issue of performance loss seems like somewhat of a corner case.
>> 
>> 
>> Sean
> 
> ok so this is the reason, good to know...
> 
> Fawzi

a memory barrier would be needed, and atomic decrements, but I see that it is not portable...

December 06, 2008
Sean Kelly, el  5 de diciembre a las 23:33 me escribiste:
> dsimcha wrote:
> >According to both the docs and my own experiments, thread_needLock() in core.thread returns a bool that depends on whether the current process has *ever* been multithreaded at *any* point in its execution.  In Phobos's GC (pre-druntime), a similar function existed, but it returned a bool based on whether more than 1 thread was *currently* running.  It seems to me that omitting locks should be safe if no more than 1 thread is currently running, even if more than 1 was running at some point in the past.  Why is druntime's thread_needLock() designed the way it is?
> 
> Typically, the stores of a terminating thread are only guaranteed to be visible when join() returns for that thread... and then to the joining thread only.  While it's true that the stores will eventually be visible to all threads in a program, there's no easy way to figure out exactly when this is (the lock-free people would probably say you'd have to wait for a "quiescent state").  I also don't know of any apps that are multi threaded for a while and then later become single threaded, so the issue of performance loss seems like somewhat of a corner case.

FYI, I've added this to the druntime FAQ: http://www.dsource.org/projects/druntime/wiki/DevelFAQ

-- 
Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/
----------------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------------
Karma police
arrest this man,
he talks in maths,
he buzzes like a fridge,
he's like a detuned radio.
December 06, 2008
Fawzi Mohamed wrote:
> So yes one could probably switch back to the old Phobos style.
> I would guess that it is not really a common situation for a program to become single threaded again, though...
> 
> Fawzi
> 

At work, we have a single-threaded application -- everything happens on the GUI thread. There are some operations that take a long time, though. For those, we throw up a spinny dialog box. But if these operations happened on the GUI thread, the spinny dialog box would not spin. So we do the expensive operations on a background thread.

So, our application becomes multithreaded on rare occasions and becomes single-threaded again after.

Not sure how common this is.
December 06, 2008
Christopher Wright, el  6 de diciembre a las 09:06 me escribiste:
> Fawzi Mohamed wrote:
> >So yes one could probably switch back to the old Phobos style.
> >I would guess that it is not really a common situation for a program to become single threaded again, though...
> >Fawzi
> 
> At work, we have a single-threaded application -- everything happens on the GUI thread. There are some operations that take a long time, though. For those, we throw up a spinny dialog box. But if these operations happened on the GUI thread, the spinny dialog box would not spin. So we do the expensive operations on a background thread.
> 
> So, our application becomes multithreaded on rare occasions and becomes single-threaded again after.
> 
> Not sure how common this is.

I think this is pretty common in GUI applications, but I don't think GUI applications usually are performance critical, right?

-- 
Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/
----------------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------------
You can do better than me. You could throw a dart out the window and hit
someone better than me. I'm no good!
	-- George Constanza
December 06, 2008
Fawzi Mohamed wrote:
> 
> a memory barrier would be needed, and atomic decrements, but I see that it is not portable...

It would also somewhat defeat the purpose of thread_needLock, since IMO this routine should be fast.  If memory barriers are involved then it may as well simply use a mutex itself, and this is exactly what it's intended to avoid.


Sean
December 06, 2008
On 2008-12-06 17:13:34 +0100, Sean Kelly <sean@invisibleduck.org> said:

> Fawzi Mohamed wrote:
>> 
>> a memory barrier would be needed, and atomic decrements, but I see that it is not portable...
> 
> It would also somewhat defeat the purpose of thread_needLock, since IMO this routine should be fast.  If memory barriers are involved then it may as well simply use a mutex itself, and this is exactly what it's intended to avoid.

the memory barrier would be needed in the code that decrements the number of active threads, so that you are sure that no pending writes are still there, (that is the problem that you said brought you to switch to a multithreaded flag), not in the code of thread_needLock...

But again I would say that this optimization is not really worth it (as you also said it), even if it is relevant for GUI applications.

Fawzi

« First   ‹ Prev
1 2