December 18, 2010 Re: Threads and static initialization. | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Sat, 18 Dec 2010 03:06:26 +0200, Jonathan M Davis <jmdavisProg@gmx.com> wrote: > And how about every other variable? I'm sorry, I'm not following you. What other variables? * Globals and class/struct/function statics are in TLS * Explicitly shared vars are in the data segment * Locals are in the stack or registers (no problem here) * Everything else (as referenced by the above three) is in the heap -- Best regards, Vladimir mailto:vladimir@thecybershadow.net | |||
December 18, 2010 Re: Threads and static initialization. | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Vladimir Panteleev | On Friday 17 December 2010 19:52:19 Vladimir Panteleev wrote:
> On Sat, 18 Dec 2010 03:06:26 +0200, Jonathan M Davis <jmdavisProg@gmx.com>
>
> wrote:
> > And how about every other variable?
>
> I'm sorry, I'm not following you. What other variables?
>
> * Globals and class/struct/function statics are in TLS
> * Explicitly shared vars are in the data segment
> * Locals are in the stack or registers (no problem here)
> * Everything else (as referenced by the above three) is in the heap
Value types which on the stack are going to be okay. That's true. You're right. They wouldn't be in TLS.
However, anything that involves the heap wouldn't be okay, and that's a _lot_ of variables. Any and all references and pointers - inluding dynamic arrays - would be in TLS unless you marked them as shared. So, you'd have to use shared all over the place except in very simple cases or cases where you went out of your way to avoid using the heap.
D is designed to avoid using shared memory except in cases where data is immutable. So, if you try to set up your program so that it uses shared memory primarily, then you're going to have problems. And not calling the static constructors on thread creation would mean using shared memory for everything which uses the heap. You couldn't even create local variables which are class objects using TLS in such a case, because they might have a static constructor which then would never have been called.
Really, I don't think that trying to avoid calling static constructors is going to work very well. It may very well be a good reason to minimize what's done in static constructors, but skipping them entirely would be very difficult to pull off safely.
- Jonathan M Davis
| |||
December 18, 2010 Re: Threads and static initialization. | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On 12/18/2010 07:53 AM, Jonathan M Davis wrote:
> On Friday 17 December 2010 19:52:19 Vladimir Panteleev wrote:
>> On Sat, 18 Dec 2010 03:06:26 +0200, Jonathan M Davis<jmdavisProg@gmx.com>
>>
>> wrote:
>>> And how about every other variable?
>>
>> I'm sorry, I'm not following you. What other variables?
>>
>> * Globals and class/struct/function statics are in TLS
>> * Explicitly shared vars are in the data segment
>> * Locals are in the stack or registers (no problem here)
>> * Everything else (as referenced by the above three) is in the heap
>
> Value types which on the stack are going to be okay. That's true. You're right.
> They wouldn't be in TLS.
>
> However, anything that involves the heap wouldn't be okay, and that's a _lot_ of
> variables. Any and all references and pointers - inluding dynamic arrays - would
> be in TLS unless you marked them as shared. So, you'd have to use shared all
> over the place except in very simple cases or cases where you went out of your
> way to avoid using the heap.
>
> D is designed to avoid using shared memory except in cases where data is
> immutable. So, if you try to set up your program so that it uses shared memory
> primarily, then you're going to have problems. And not calling the static
> constructors on thread creation would mean using shared memory for everything
> which uses the heap. You couldn't even create local variables which are class
> objects using TLS in such a case, because they might have a static constructor
> which then would never have been called.
>
> Really, I don't think that trying to avoid calling static constructors is going
> to work very well. It may very well be a good reason to minimize what's done in
> static constructors, but skipping them entirely would be very difficult to pull off
> safely.
>
> - Jonathan M Davis
The heap is the heap is the heap. You can have local variables on the heap which are not shared. I think you are overstating the need for shared, probably some misunderstanding.
You could not have classes/structs with static members, or call functions with static variables. Everything else should work, probably.
The spawned thread could use the parent thread immutable globals, to avoid the need to construct them in the spawned tls. I don't know if this is actually possible :-)
| |||
December 18, 2010 Re: Threads and static initialization. | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Pelle Månsson | On Friday 17 December 2010 23:56:37 Pelle Månsson wrote:
> On 12/18/2010 07:53 AM, Jonathan M Davis wrote:
> > On Friday 17 December 2010 19:52:19 Vladimir Panteleev wrote:
> >> On Sat, 18 Dec 2010 03:06:26 +0200, Jonathan M Davis<jmdavisProg@gmx.com>
> >>
> >> wrote:
> >>> And how about every other variable?
> >>
> >> I'm sorry, I'm not following you. What other variables?
> >>
> >> * Globals and class/struct/function statics are in TLS
> >> * Explicitly shared vars are in the data segment
> >> * Locals are in the stack or registers (no problem here)
> >> * Everything else (as referenced by the above three) is in the heap
> >
> > Value types which on the stack are going to be okay. That's true. You're right. They wouldn't be in TLS.
> >
> > However, anything that involves the heap wouldn't be okay, and that's a _lot_ of variables. Any and all references and pointers - inluding dynamic arrays - would be in TLS unless you marked them as shared. So, you'd have to use shared all over the place except in very simple cases or cases where you went out of your way to avoid using the heap.
> >
> > D is designed to avoid using shared memory except in cases where data is immutable. So, if you try to set up your program so that it uses shared memory primarily, then you're going to have problems. And not calling the static constructors on thread creation would mean using shared memory for everything which uses the heap. You couldn't even create local variables which are class objects using TLS in such a case, because they might have a static constructor which then would never have been called.
> >
> > Really, I don't think that trying to avoid calling static constructors is going to work very well. It may very well be a good reason to minimize what's done in static constructors, but skipping them entirely would be very difficult to pull off safely.
> >
> > - Jonathan M Davis
>
> The heap is the heap is the heap. You can have local variables on the heap which are not shared. I think you are overstating the need for shared, probably some misunderstanding.
>
> You could not have classes/structs with static members, or call functions with static variables. Everything else should work, probably.
>
> The spawned thread could use the parent thread immutable globals, to avoid the need to construct them in the spawned tls. I don't know if this is actually possible :-)
The problem is that the OP wants the static constructors to be skipped. If they're skipped, anything and everything which could be affected by that can't be used. That pretty much means not using TLS, since the compiler isn't going to be able to track down which variables in TLS will or won't be affected by it. So, you're stuck using shared memory only. _That_ is where the problem comes in.
As for immutable globals, in theory at least (I believe there's an open bug on the issue at the moment), global immutables are all shared. If all that's done correctly, in theory, you'd just create the immutable globals either at compile time or with static constructors (possibly shared or immutable ones) which are just run once and don't have to be run per thread. So, immutable globals shouldn't pose a problem. However, mutable ones would - including those for classes. Because they'd need their static constructors run on thread creation in order to be properly initialized.
- Jonathan M Davis
- Jonathan M Davis
| |||
December 18, 2010 Re: Threads and static initialization. | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On 12/18/2010 10:00 AM, Jonathan M Davis wrote:
> The problem is that the OP wants the static constructors to be skipped. If
> they're skipped, anything and everything which could be affected by that can't be
> used. That pretty much means not using TLS, since the compiler isn't going to be
> able to track down which variables in TLS will or won't be affected by it. So,
> you're stuck using shared memory only. _That_ is where the problem comes in.
Exactly, not using TLS. You can still use the heap, as it is not thread local. Meaning you can create non-shared anything all you like, as long as you're not using TLS.
| |||
December 18, 2010 Re: Threads and static initialization. | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On 2010-12-18 01:53:04 -0500, Jonathan M Davis <jmdavisProg@gmx.com> said: > However, anything that involves the heap wouldn't be okay, and that's a _lot_ of > variables. Any and all references and pointers - inluding dynamic arrays - would > be in TLS unless you marked them as shared. Things stored in the heap are *not* stored in thread-local storage. TLS is for thread-local global and static variables. Having TLS variables uninitialized shouldn't a problem when playing with the heap. -- Michel Fortin michel.fortin@michelf.com http://michelf.com/ | |||
December 18, 2010 Re: Threads and static initialization. | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Pelle Månsson | On Sat, 18 Dec 2010 03:27:22 -0700, Pelle Månsson <pelle.mansson@gmail.com> wrote:
> On 12/18/2010 10:00 AM, Jonathan M Davis wrote:
>> The problem is that the OP wants the static constructors to be skipped. If
>> they're skipped, anything and everything which could be affected by that can't be
>> used. That pretty much means not using TLS, since the compiler isn't going to be
>> able to track down which variables in TLS will or won't be affected by it. So,
>> you're stuck using shared memory only. _That_ is where the problem comes in.
>
> Exactly, not using TLS. You can still use the heap, as it is not thread local. Meaning you can create non-shared anything all you like, as long as you're not using TLS.
Except that the 'heap' internally uses TLS. The GC does need and use TLS.
| |||
December 18, 2010 Re: Threads and static initialization. | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Robert Jacques | On 2010-12-18 15:57:50 -0500, "Robert Jacques" <sandford@jhu.edu> said: > On Sat, 18 Dec 2010 03:27:22 -0700, Pelle Månsson <pelle.mansson@gmail.com> wrote: > >> On 12/18/2010 10:00 AM, Jonathan M Davis wrote: >>> The problem is that the OP wants the static constructors to be skipped. If >>> they're skipped, anything and everything which could be affected by that can't be >>> used. That pretty much means not using TLS, since the compiler isn't going to be >>> able to track down which variables in TLS will or won't be affected by it. So, >>> you're stuck using shared memory only. _That_ is where the problem comes in. >> >> Exactly, not using TLS. You can still use the heap, as it is not thread local. Meaning you can create non-shared anything all you like, as long as you're not using TLS. > > Except that the 'heap' internally uses TLS. The GC does need and use TLS. Using D's TLS for the GC is an implementation choice, not a requirement. If someone wants to optimize 'spawn' for pure functions by skipping D's TLS initialization, he can make the GC and the array appending cache work with that. -- Michel Fortin michel.fortin@michelf.com http://michelf.com/ | |||
December 18, 2010 Re: Threads and static initialization. | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Michel Fortin | On Sat, 18 Dec 2010 15:04:38 -0700, Michel Fortin <michel.fortin@michelf.com> wrote:
> On 2010-12-18 15:57:50 -0500, "Robert Jacques" <sandford@jhu.edu> said:
>
>> On Sat, 18 Dec 2010 03:27:22 -0700, Pelle Månsson <pelle.mansson@gmail.com> wrote:
>>
>>> On 12/18/2010 10:00 AM, Jonathan M Davis wrote:
>>>> The problem is that the OP wants the static constructors to be skipped. If
>>>> they're skipped, anything and everything which could be affected by that can't be
>>>> used. That pretty much means not using TLS, since the compiler isn't going to be
>>>> able to track down which variables in TLS will or won't be affected by it. So,
>>>> you're stuck using shared memory only. _That_ is where the problem comes in.
>>> Exactly, not using TLS. You can still use the heap, as it is not thread local. Meaning you can create non-shared anything all you like, as long as you're not using TLS.
>> Except that the 'heap' internally uses TLS. The GC does need and use TLS.
>
> Using D's TLS for the GC is an implementation choice, not a requirement. If someone wants to optimize 'spawn' for pure functions by skipping D's TLS initialization, he can make the GC and the array appending cache work with that.
>
Not really, as _every_ modern GC requires TLS. And we're talking about a performance optimization here: not supporting modern GCs in order to remove TLS initialization would be a penny-wise pound foolish move. Besides, 'mini' threads shouldn't be created using OS threads; that's what thread-pools, fibers and tasks are for.
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply