| Thread overview | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
February 24, 2010 Light-weight threads | ||||
|---|---|---|---|---|
| ||||
Hi there, I just found that recent change in the language to make all global variables thread-local by default. This makes me think of a major performance problem: every thread creation will have to copy all the thread-local variables. This makes it impossible to efficiently spawn many light-weight threads even if they do not make use of the global variables at all. I guess I am not the first one to spot this problem? I believe that thread creation should come with as little overhead as possible. Maybe a concept of light-weight threads based on side-effect free code could complement the regular threads? Just a quick idea to throw into discussion... Greetings, Norbert | ||||
February 24, 2010 Re: Light-weight threads | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Norbert Nemec | == Quote from Norbert Nemec (Norbert@Nemec-online.de)'s article
> Hi there,
> I just found that recent change in the language to make all global
> variables thread-local by default. This makes me think of a major
> performance problem: every thread creation will have to copy all the
> thread-local variables. This makes it impossible to efficiently spawn
> many light-weight threads even if they do not make use of the global
> variables at all.
> I guess I am not the first one to spot this problem? I believe that
> thread creation should come with as little overhead as possible. Maybe a
> concept of light-weight threads based on side-effect free code could
> complement the regular threads?
> Just a quick idea to throw into discussion...
> Greetings,
> Norbert
What's wrong with using thread/task pools for these situations?
| |||
February 24, 2010 Re: Light-weight threads | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Norbert Nemec | On 2/24/10 2:15 AM, Norbert Nemec wrote:
> Hi there,
>
> I just found that recent change in the language to make all global
> variables thread-local by default. This makes me think of a major
> performance problem: every thread creation will have to copy all the
> thread-local variables. This makes it impossible to efficiently spawn
> many light-weight threads even if they do not make use of the global
> variables at all.
>
> I guess I am not the first one to spot this problem? I believe that
> thread creation should come with as little overhead as possible. Maybe a
> concept of light-weight threads based on side-effect free code could
> complement the regular threads?
>
> Just a quick idea to throw into discussion...
>
> Greetings,
> Norbert
That is why features like "immutability by default" are important. You don't have to copy immutable objects.
| |||
February 24, 2010 Re: Light-weight threads | ||||
|---|---|---|---|---|
| ||||
Posted in reply to ds | ds wrote:
> == Quote from Norbert Nemec (Norbert@Nemec-online.de)'s article
>> Hi there,
>> I just found that recent change in the language to make all global
>> variables thread-local by default. This makes me think of a major
>> performance problem: every thread creation will have to copy all the
>> thread-local variables. This makes it impossible to efficiently spawn
>> many light-weight threads even if they do not make use of the global
>> variables at all.
>> I guess I am not the first one to spot this problem? I believe that
>> thread creation should come with as little overhead as possible. Maybe a
>> concept of light-weight threads based on side-effect free code could
>> complement the regular threads?
>> Just a quick idea to throw into discussion...
>> Greetings,
>> Norbert
>
> What's wrong with using thread/task pools for these situations?
That's always an option, of course. It just adds one layer of complexity to the code.
If spawning a thread were as cheap as putting a task in a queue you could simply spawn one thread per task and leave it to the scheduler to handle it all. Assuming, of course, that the scheduler is clever enough to handle it efficiently.
| |||
February 24, 2010 Re: Light-weight threads | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Norbert Nemec | On 2/24/10 7:57 AM, Norbert Nemec wrote:
> ds wrote:
>> == Quote from Norbert Nemec (Norbert@Nemec-online.de)'s article
>>> Hi there,
>>> I just found that recent change in the language to make all global
>>> variables thread-local by default. This makes me think of a major
>>> performance problem: every thread creation will have to copy all the
>>> thread-local variables. This makes it impossible to efficiently spawn
>>> many light-weight threads even if they do not make use of the global
>>> variables at all.
>>> I guess I am not the first one to spot this problem? I believe that
>>> thread creation should come with as little overhead as possible. Maybe a
>>> concept of light-weight threads based on side-effect free code could
>>> complement the regular threads?
>>> Just a quick idea to throw into discussion...
>>> Greetings,
>>> Norbert
>>
>> What's wrong with using thread/task pools for these situations?
>
> That's always an option, of course. It just adds one layer of complexity
> to the code.
>
> If spawning a thread were as cheap as putting a task in a queue you
> could simply spawn one thread per task and leave it to the scheduler to
> handle it all. Assuming, of course, that the scheduler is clever enough
> to handle it efficiently.
The problem is they are divergent. If I spawn a thread to reorder an array for the UI, then of course I use that thread again for the same task, its array hasn't been updated by all the new elements that the original was keeping track of. Right? I guess you could make it shared, but then how is it better than using a traditional language?
| |||
February 24, 2010 Re: Light-weight threads | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Norbert Nemec | On Wed, 24 Feb 2010 04:15:03 -0500, Norbert Nemec <Norbert@nemec-online.de> wrote:
> Hi there,
>
> I just found that recent change in the language to make all global variables thread-local by default. This makes me think of a major performance problem: every thread creation will have to copy all the thread-local variables. This makes it impossible to efficiently spawn many light-weight threads even if they do not make use of the global variables at all.
>
> I guess I am not the first one to spot this problem? I believe that thread creation should come with as little overhead as possible. Maybe a concept of light-weight threads based on side-effect free code could complement the regular threads?
>
> Just a quick idea to throw into discussion...
>
> Greetings,
> Norbert
Norbert, you are confusing threads with fibers. OS Threads have never been, nor will ever be, "light-weight" in any sense of the word. If they were, no one would care about thread-pools and the like. Languages that feature light-weight threads, such as Erlang, are actually spawning fibers. The Erlang runtime, for example, only ever uses one D style thread to host millions of 'logical' threads.
Basic fiber support is already in druntime. Actually, it looks like the std.thread and std.concurrency updates will internally use either a thread pool or a fiber based back-end, so you might not have to worry about it. If you're simply looking for a task library, dsimcha has been working on one as have others (look in scrapple and for the blip project on dsource, IIRC)
| |||
February 24, 2010 Re: Light-weight threads | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Robert Jacques | Robert Jacques wrote:
> Norbert, you are confusing threads with fibers. OS Threads have never been, nor will ever be, "light-weight" in any sense of the word.
What I had in mind were discussions about OSes that make thread creation extremely cheap, but indeed: OS threads will probably always carry sufficient overhead to leave plenty of room for application-level mechanism...
Does anyone know how expensive thread creation is for typical and for experimental OSes? How does this compare to the overhead of initializing thread-local data? I.e.: How much should one actually worry about TLS?
| |||
February 24, 2010 Re: Light-weight threads | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Norbert Nemec | Norbert Nemec Wrote:
> Robert Jacques wrote:
> > Norbert, you are confusing threads with fibers. OS Threads have never been, nor will ever be, "light-weight" in any sense of the word.
>
> What I had in mind were discussions about OSes that make thread creation extremely cheap, but indeed: OS threads will probably always carry sufficient overhead to leave plenty of room for application-level mechanism...
>
> Does anyone know how expensive thread creation is for typical and for experimental OSes? How does this compare to the overhead of initializing thread-local data? I.e.: How much should one actually worry about TLS?
Your worries looks like 'premature optimization' to me. I had little experieance with similar story while ago, web server that was happily creating bunch of threads for each request. XP handled it well, up to couple hundred threads, then started to suffocate. CentOS did better up to 1000, then some strange bugs emerged. On both I had to do manual memory management as GC wasn't smart enough (finished thead is not deleted thread, and os wont give you more before). Most headaches were. of course, synchronization of operations on complex data types (arrays and such), handles etc.
Hate to say it, but there were some issues I couldn't track down, so I switched to multi process instead of multi threaded, and it works fine :D
Lot of people are saying that threads are evil. There might be something in it :D
| |||
February 25, 2010 Re: Light-weight threads | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Robert Jacques | > Norbert, you are confusing threads with fibers. OS Threads have never
> been, nor will ever be, "light-weight" in any sense of the word. If they
> were, no one would care about thread-pools and the like. Languages that
> feature light-weight threads, such as Erlang, are actually spawning
> fibers. The Erlang runtime, for example, only ever uses one D style
> thread to host millions of 'logical' threads.
Actually, newer versions of Erlang now use multiple threads, typically 1 per CPU and one pool of processes and a scheduler per thread. Processes can also be moved between threads in case one is busier than the others.
Casey
| |||
February 25, 2010 Re: Light-weight threads | ||||
|---|---|---|---|---|
| ||||
Posted in reply to sybrandy | On Wed, 24 Feb 2010 21:08:02 -0500, sybrandy <sybrandy@gmail.com> wrote:
>> Norbert, you are confusing threads with fibers. OS Threads have never
>> been, nor will ever be, "light-weight" in any sense of the word. If they
>> were, no one would care about thread-pools and the like. Languages that
>> feature light-weight threads, such as Erlang, are actually spawning
>> fibers. The Erlang runtime, for example, only ever uses one D style
>> thread to host millions of 'logical' threads.
>
> Actually, newer versions of Erlang now use multiple threads, typically 1 per CPU and one pool of processes and a scheduler per thread. Processes can also be moved between threads in case one is busier than the others.
>
> Casey
I looked into this 1 or 2 years ago. Erlang was designed for the cluster, so they just use multiple processes (1 per CPU) not multiple threads. There's very little little overhead to this technique and it was a simple, elegant and trivial solution. Besides there are a lot of pitfalls to going to a true multi-threaded runtime, not the least of which is the GC. There are a lot of technical issues which make moving fibers between threads very dangerous: doing so requires you to be aware of all the operations you can't use/do and to program around them accordingly. Otherwise you end up with data races.
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply