28.07.2021 17:39, Mathias LANG пишет:
On Wednesday, 21 July 2021 at 22:51:38 UTC, hanabi1224 wrote:
Hi, I'm new to D lang and encounter some performance issues with
fiber, not sure if there's something obviously wrong with my code.
I took a quick look, and the first problem I saw was that you were using
`spawnLinked` but not replacing the scheduler.
`std.concurrency` uses a global `scheduler` variable to do its job.
Hence doing:
```diff
- auto scheduler = new FiberScheduler();
+ scheduler = new FiberScheduler();
```
Will ensure that `spawnLinked` works as expected.
There are a few other things to consider, w.r.t. fibers:
- Our Fibers are 4 pages (on Linux) by default;
- We have an extra guard page, because we are a native language, so we
can't do the same trick as Go to auto-grow the stack;
- Spawning fibers *is* expensive and other languages reuse fibers (Yes,
Go recycle them);
The `FiberScheduler` implementation is unfortunately pretty bad: it
[does not re-use
fibers](https://github.com/dlang/phobos/blob/b48cca57e8ad2dc56872499836bfa1e70e390abb/std/concurrency.d#L1578-L1599).
I believe this is the core of the issue.
I profiled the provided example (not `FiberScheduler`) using perf. Both
dmd and ldc2 gave the same result - `void filterInner(int, int)` took
~90% of the run time. The time was divided between:
`int std.concurrency.receiveOnly!(int).receiveOnly()` - 58%
`void std.concurrency.send!(int).send(std.concurrency.Tid, int)` - 31%
So most of the time is messages passing.
Between the fibers creating took very few time. Perf output contains
information only of `void std.concurrency.FiberScheduler.create(void
delegate()).wrap()` which took less than 0.5%. But I wouldn't say that I
did the profiling ideally so take it with a grain of salt.