Jump to page: 1 2 3
Thread overview
Are Fibers just broken in D?
Apr 20, 2018
Byron Moxie
Apr 20, 2018
rikki cattermole
Apr 20, 2018
Byron Moxie
Apr 24, 2018
Byron Heads
Apr 24, 2018
Radu
Apr 24, 2018
bauss
Apr 24, 2018
Radu
Apr 24, 2018
Radu
Apr 24, 2018
Byron Heads
Apr 24, 2018
kinke
Apr 24, 2018
rikki cattermole
Apr 25, 2018
bitwise
April 20, 2018
I am working on an application that makes heavy use of Fibers pools that are processed by a thread pool.

In WIN32 it looks like its leaking memory then it segfaults (I am guessing its an OOM).

I am also trying to use Semaphores and/or Conditions on shared data between fibers, which results in segfaults as well.

atomicLoad and atomicStore are not working either.

Are Fibers usable at all?  Cause it doesn't seem like.  I already re-arched this application to remove vibe.d (was fighting all sorts of sync and event errors)

This application is turning into my last straw for D..  I spend about 90% of my time fighting the compiler / library. I am really debating re-writing this application in c++ over the weekend (I have already lost money on this job after convincing by boss that D would be better).
April 21, 2018
On 21/04/2018 6:58 AM, Byron Moxie wrote:
> I am working on an application that makes heavy use of Fibers pools that are processed by a thread pool.
> 
> In WIN32 it looks like its leaking memory then it segfaults (I am guessing its an OOM).
> 
> I am also trying to use Semaphores and/or Conditions on shared data between fibers, which results in segfaults as well.
> 
> atomicLoad and atomicStore are not working either.
> 
> Are Fibers usable at all?  Cause it doesn't seem like.  I already re-arched this application to remove vibe.d (was fighting all sorts of sync and event errors)
> 
> This application is turning into my last straw for D..  I spend about 90% of my time fighting the compiler / library. I am really debating re-writing this application in c++ over the weekend (I have already lost money on this job after convincing by boss that D would be better).

atomicLoad and atomicStore, definitely are working.

It sounds like you have got some pretty big problems that may not be on D's end.

But we'll need code to be able to help you further than that.
April 20, 2018
On 4/20/18 2:58 PM, Byron Moxie wrote:
> I am working on an application that makes heavy use of Fibers pools that are processed by a thread pool.
> 
> In WIN32 it looks like its leaking memory then it segfaults (I am guessing its an OOM).
> 
> I am also trying to use Semaphores and/or Conditions on shared data between fibers, which results in segfaults as well.
> 
> atomicLoad and atomicStore are not working either.
> 
> Are Fibers usable at all?  Cause it doesn't seem like.  I already re-arched this application to remove vibe.d (was fighting all sorts of sync and event errors)
> 
> This application is turning into my last straw for D..  I spend about 90% of my time fighting the compiler / library. I am really debating re-writing this application in c++ over the weekend (I have already lost money on this job after convincing by boss that D would be better).

It sounds like the problems may be due to Win32 and not the other pieces. Have you tried on a Win64 build? Even if that's not your target, at least it can help you discover whether that is the problem or not. The DMC runtime is the default on Win32, and it's not especially thread-safe in all places.

FWIW, I'm using vibe.d on Linux 64 bit with no problems (and I've NEVER heard of atomicLoad and atomicStore not working on any arch).

-Steve
April 20, 2018
On Friday, 20 April 2018 at 20:46:20 UTC, Steven Schveighoffer wrote:
> On 4/20/18 2:58 PM, Byron Moxie wrote:
>> [...]
>
> It sounds like the problems may be due to Win32 and not the other pieces. Have you tried on a Win64 build? Even if that's not your target, at least it can help you discover whether that is the problem or not. The DMC runtime is the default on Win32, and it's not especially thread-safe in all places.
>
> FWIW, I'm using vibe.d on Linux 64 bit with no problems (and I've NEVER heard of atomicLoad and atomicStore not working on any arch).
>
> -Steve

I had move the data I wanted to sync with atomicLoad/Store into a shared struct and pass a pointer to this struct to the other fibers. Not sure if this was an issue with TLS messing with class object I was passing around.
April 24, 2018
On Friday, 20 April 2018 at 20:52:17 UTC, Byron Moxie wrote:
> On Friday, 20 April 2018 at 20:46:20 UTC, Steven Schveighoffer wrote:
>> On 4/20/18 2:58 PM, Byron Moxie wrote:
>>> [...]
>>
>> It sounds like the problems may be due to Win32 and not the other pieces. Have you tried on a Win64 build? Even if that's not your target, at least it can help you discover whether that is the problem or not. The DMC runtime is the default on Win32, and it's not especially thread-safe in all places.
>>
>> FWIW, I'm using vibe.d on Linux 64 bit with no problems (and I've NEVER heard of atomicLoad and atomicStore not working on any arch).
>>
>> -Steve
>
> I had move the data I wanted to sync with atomicLoad/Store into a shared struct and pass a pointer to this struct to the other fibers. Not sure if this was an issue with TLS messing with class object I was passing around.



Fibers on Win32 have a memory leak for sure:

import core.thread : Fiber;

void main() {

    foreach(ulong i; 0..99_999) {
        auto foo = new Foo();
        foo.call();
        foo.call();
    }
}


class Foo : Fiber {
    this() {
        super(&run);
    }


    void run() {
        Fiber.yield();
    }
}


Running this with -m64 on windows runs without a problem, but with -m32 it failes aith a Memory Allocation failed error.



April 23, 2018
On 4/23/18 8:46 PM, Byron Heads wrote:
> Fibers on Win32 have a memory leak for sure:
> 
> import core.thread : Fiber;
> 
> void main() {
> 
>      foreach(ulong i; 0..99_999) {
>          auto foo = new Foo();
>          foo.call();
>          foo.call();
>      }
> }

It sure looks like this should be fine, the GC should clean up all the unused fibers.

> Running this with -m64 on windows runs without a problem, but with -m32 it failes aith a Memory Allocation failed error.

How many loops until you get a failure?

Is there a particular reason you need to use 32-bit Windows?

-Steve
April 24, 2018
On Tuesday, 24 April 2018 at 00:46:39 UTC, Byron Heads wrote:
> On Friday, 20 April 2018 at 20:52:17 UTC, Byron Moxie wrote:
>> On Friday, 20 April 2018 at 20:46:20 UTC, Steven Schveighoffer wrote:
>>> On 4/20/18 2:58 PM, Byron Moxie wrote:
>>>> [...]
>>>
>>> It sounds like the problems may be due to Win32 and not the other pieces. Have you tried on a Win64 build? Even if that's not your target, at least it can help you discover whether that is the problem or not. The DMC runtime is the default on Win32, and it's not especially thread-safe in all places.
>>>
>>> FWIW, I'm using vibe.d on Linux 64 bit with no problems (and I've NEVER heard of atomicLoad and atomicStore not working on any arch).
>>>
>>> -Steve
>>
>> I had move the data I wanted to sync with atomicLoad/Store into a shared struct and pass a pointer to this struct to the other fibers. Not sure if this was an issue with TLS messing with class object I was passing around.
>
>
>
> Fibers on Win32 have a memory leak for sure:
>
> import core.thread : Fiber;
>
> void main() {
>
>     foreach(ulong i; 0..99_999) {
>         auto foo = new Foo();
>         foo.call();
>         foo.call();
>     }
> }
>
>
> class Foo : Fiber {
>     this() {
>         super(&run);
>     }
>
>
>     void run() {
>         Fiber.yield();
>     }
> }
>
>
> Running this with -m64 on windows runs without a problem, but with -m32 it failes aith a Memory Allocation failed error.

This is not a fiber issue but a more memory management issue. Your run out of address space on win32, the GC will not always collect all those 99999 fibers that you allocate in that loop. As an exercise replace `auto` with `scope` like `scope foo = new Foo();` in that loop - you should see different results.

The issue boils down to the call to VirtualAlloc that the fiber constructor makes, which fails as Windows will not allocate any more virtual pages for the process. If you really want that many fibers you should reconsider 32 bit, and definitely use a different allocation strategy.
April 24, 2018
On Tuesday, 24 April 2018 at 07:58:01 UTC, Radu wrote:
> On Tuesday, 24 April 2018 at 00:46:39 UTC, Byron Heads wrote:
>> On Friday, 20 April 2018 at 20:52:17 UTC, Byron Moxie wrote:
>>> On Friday, 20 April 2018 at 20:46:20 UTC, Steven Schveighoffer wrote:
>>>> On 4/20/18 2:58 PM, Byron Moxie wrote:
>>>>> [...]
>>>>
>>>> It sounds like the problems may be due to Win32 and not the other pieces. Have you tried on a Win64 build? Even if that's not your target, at least it can help you discover whether that is the problem or not. The DMC runtime is the default on Win32, and it's not especially thread-safe in all places.
>>>>
>>>> FWIW, I'm using vibe.d on Linux 64 bit with no problems (and I've NEVER heard of atomicLoad and atomicStore not working on any arch).
>>>>
>>>> -Steve
>>>
>>> I had move the data I wanted to sync with atomicLoad/Store into a shared struct and pass a pointer to this struct to the other fibers. Not sure if this was an issue with TLS messing with class object I was passing around.
>>
>>
>>
>> Fibers on Win32 have a memory leak for sure:
>>
>> import core.thread : Fiber;
>>
>> void main() {
>>
>>     foreach(ulong i; 0..99_999) {
>>         auto foo = new Foo();
>>         foo.call();
>>         foo.call();
>>     }
>> }
>>
>>
>> class Foo : Fiber {
>>     this() {
>>         super(&run);
>>     }
>>
>>
>>     void run() {
>>         Fiber.yield();
>>     }
>> }
>>
>>
>> Running this with -m64 on windows runs without a problem, but with -m32 it failes aith a Memory Allocation failed error.
>
> This is not a fiber issue but a more memory management issue. Your run out of address space on win32, the GC will not always collect all those 99999 fibers that you allocate in that loop. As an exercise replace `auto` with `scope` like `scope foo = new Foo();` in that loop - you should see different results.
>
> The issue boils down to the call to VirtualAlloc that the fiber constructor makes, which fails as Windows will not allocate any more virtual pages for the process. If you really want that many fibers you should reconsider 32 bit, and definitely use a different allocation strategy.

And in the end of the day it makes no sense to have that many fibers as they would probably perform terrible.
April 24, 2018
On 4/24/18 5:11 AM, bauss wrote:
> On Tuesday, 24 April 2018 at 07:58:01 UTC, Radu wrote:
>> On Tuesday, 24 April 2018 at 00:46:39 UTC, Byron Heads wrote:
>>>
>>> Fibers on Win32 have a memory leak for sure:
>>>
>>> import core.thread : Fiber;
>>>
>>> void main() {
>>>
>>>     foreach(ulong i; 0..99_999) {
>>>         auto foo = new Foo();
>>>         foo.call();
>>>         foo.call();
>>>     }
>>> }
>>>
>>>
>>> class Foo : Fiber {
>>>     this() {
>>>         super(&run);
>>>     }
>>>
>>>
>>>     void run() {
>>>         Fiber.yield();
>>>     }
>>> }
>>>
>>>
>>> Running this with -m64 on windows runs without a problem, but with -m32 it failes aith a Memory Allocation failed error.
>>
>> This is not a fiber issue but a more memory management issue. Your run out of address space on win32, the GC will not always collect all those 99999 fibers that you allocate in that loop. As an exercise replace `auto` with `scope` like `scope foo = new Foo();` in that loop - you should see different results.

This shouldn't be a requirement, the 32-bit GC is generally not this bad.

>>
>> The issue boils down to the call to VirtualAlloc that the fiber constructor makes, which fails as Windows will not allocate any more virtual pages for the process. If you really want that many fibers you should reconsider 32 bit, and definitely use a different allocation strategy.
> 
> And in the end of the day it makes no sense to have that many fibers as they would probably perform terrible.

Let's not forget though, that he's executing the fiber completely within the loop. It should be done and collected.

This is not the case of executing 100,000 concurrent fibers, but executing 100,000 *sequential* fibers. It should work just fine.

-Steve
April 24, 2018
On Tuesday, 24 April 2018 at 13:36:48 UTC, Steven Schveighoffer wrote:
> On 4/24/18 5:11 AM, bauss wrote:
>> On Tuesday, 24 April 2018 at 07:58:01 UTC, Radu wrote:
>>> On Tuesday, 24 April 2018 at 00:46:39 UTC, Byron Heads wrote:
>>>> [...]
>>>
>>> This is not a fiber issue but a more memory management issue. Your run out of address space on win32, the GC will not always collect all those 99999 fibers that you allocate in that loop. As an exercise replace `auto` with `scope` like `scope foo = new Foo();` in that loop - you should see different results.
>
> This shouldn't be a requirement, the 32-bit GC is generally not this bad.
>

Allocating so many fibers in a loop produces an OOM error on win32, that's a fact! Event though it doesn't always happen you often get OOM errors with the program above.

Probably the cause is related to how often the collection kicks in in relation to the pages allocated via VirtualAlloc. But still, the issue OP raised is not a Fiber related issue but a memory management issue.

>>>
>>> The issue boils down to the call to VirtualAlloc that the fiber constructor makes, which fails as Windows will not allocate any more virtual pages for the process. If you really want that many fibers you should reconsider 32 bit, and definitely use a different allocation strategy.
>> 
>> And in the end of the day it makes no sense to have that many fibers as they would probably perform terrible.
>
> Let's not forget though, that he's executing the fiber completely within the loop. It should be done and collected.
>
> This is not the case of executing 100,000 concurrent fibers, but executing 100,000 *sequential* fibers. It should work just fine.
>
> -Steve

« First   ‹ Prev
1 2 3