Jump to page: 1 210  
Page
Thread overview
Tasks, actors and garbage collection
Apr 20
russhy
Apr 20
russhy
Apr 20
russhy
Apr 20
russhy
Apr 20
russhy
Apr 20
russhy
Apr 20
evilrat
Apr 21
russhy
Apr 20
russhy
Apr 25
russhy
Apr 25
evilrat
Apr 25
russhy
Apr 25
russhy
Apr 26
evilrat
Apr 26
russhy
Apr 26
russhy
Apr 26
russhy
Apr 26
russhy
Apr 27
russhy
Apr 27
russhy
Apr 27
sclytrack
Apr 27
evilrat
Apr 27
sighoya
Apr 28
sighoya
Apr 27
russhy
Apr 28
sighoya
Apr 26
russhy
Apr 26
evilrat
Apr 26
russhy
Apr 26
bachmeier
Apr 26
evilrat
Apr 27
martinm
Apr 26
russhy
Apr 26
russhy
Apr 20
russhy
Re: Tasks, actors and garbage collection (OFFTOPIC)
Apr 21
russhy
Apr 21
TheGag96
Apr 21
russhy
Apr 25
russhy
Apr 20
jmh530
Apr 27
Jossy
Apr 27
sighoya
May 03
Tejas
Apr 29
James Lu
April 20

As computer memory grows, naive scan and sweep garbage collection becomes more and more a burden.

Also, languages have not really come up with a satisfactory way to simplify multi-threaded programming, except to split the workload into many single-threaded tasks that are run in parallel.

It seems to me that the obvious way to retain the easy of use that garbage collection provides without impeding performance is to limit the memory to scan, and preferably do the scanning when nobody is using the memory.

The actor model seems to be a good fit. Or call it a task, if you wish. If each actor/task has it's own GC pool then there is less memory to scan, and you can do the scanning when the actor/task is waiting on I/O or scheduling. So you would get less intrusive scanning pauses. It would also fit well with async-await/futures.

Another benefit is that if an actor is deleted before it is scanned, then no scanning is necessary at all. It can simply be released (assuming destructor-free classes are allocated in a separate area). This is of great benefit to web-services, they can simply implement a request-handler as an actor/task.

The downside is that you need a non-GC mechanism for dealing with inter-actor/task communication. Such as reference counting, however that should be quite ok, as you would expect the time-consuming stuff to happen within an actor/task as well as complex allocation patterns.

Is this a direction D is able to move in or is a new language needed?

April 20

On Tuesday, 20 April 2021 at 09:52:07 UTC, Ola Fosheim Grøstad wrote:

>

As computer memory grows, naive scan and sweep garbage collection becomes more and more a burden.

Also, languages have not really come up with a satisfactory way to simplify multi-threaded programming, except to split the workload into many single-threaded tasks that are run in parallel.

It seems to me that the obvious way to retain the easy of use that garbage collection provides without impeding performance is to limit the memory to scan, and preferably do the scanning when nobody is using the memory.

The actor model seems to be a good fit. Or call it a task, if you wish. If each actor/task has it's own GC pool then there is less memory to scan, and you can do the scanning when the actor/task is waiting on I/O or scheduling. So you would get less intrusive scanning pauses. It would also fit well with async-await/futures.

Another benefit is that if an actor is deleted before it is scanned, then no scanning is necessary at all. It can simply be released (assuming destructor-free classes are allocated in a separate area). This is of great benefit to web-services, they can simply implement a request-handler as an actor/task.

The downside is that you need a non-GC mechanism for dealing with inter-actor/task communication. Such as reference counting, however that should be quite ok, as you would expect the time-consuming stuff to happen within an actor/task as well as complex allocation patterns.

Is this a direction D is able to move in or is a new language needed?

A few years ago, when std.experimental.allocator was still hot out of the oven, I considered that this would one of primary innovations that it would enable.

The basic idea is that since allocators are composable first-class objects, you can pass them to any function and that way you can override and customize its memory allocation policy, without resorting to global variables.

(The package does provide convenience thread-local and global variables, but IMO that's an anti-pattern, as if you prefer the simplicity, you can either use the GC (as always), or MAllocator directly. IMO, if you're reaching for std.experimental.allocator, you do so, in order to gain more control over the memory management. Also knowing whether theAllocator points to GCAllocator, or an actually separate thread-local allocator, can be critical for ensuring that code is lock-free. You either know what you're doing, or the code is not performance critical, so it doesn't matter, and you should be using the GC anyway.)

By passing the allocator as an object, you allow it to be used safely from pure functions. (If pure functions were to somehow be allowed to use those global allocator variables, you could have some ugly consequences. For example, a pure function can be preempted in the middle of its execution, only to have the global allocator replaced under its feet, thereby leaving all the memory allocated from the previous allocator dangling.)
Pure code (even in the relaxed D sense) is great for parallelism, as a scheduler can essentially assume that it's both lock-free and wait-free - it doesn't need to interact with any other thread/fiber/task to make progress.

Having multiple per thread/fiber/actor/task GC heaps fits naturally in the model you propose. There could be a new LocalGCAllocator, which the runtime / framework can simply pass to the actor on its creation. There two main challenges:

  1. Ensuring code doesn't brake the assumptions of the actor model by e.g. sharing memory between threads in an uncontrolled manner. This can be addressed in a variety of ways:
    • The framework's build-system can prevent you from importing code that doesn't fit its model
    • The framework can run a non-optional linter as part of the build process, which would ensure that you don't have:
      • @system or @trusted code
      • extern function declarations (otherwise you could define @safe pure int printf(scope const char* format, scope const ...);)
    • reference capabilities like Pony's
    • other type-system or language built-in static analysis
  2. Making it ergonomic and easy to use, as is using the GC. Essentially having all language and library features that currently require the GC use LocalGCAllocator automagically.
    I think this can be done in several steps:
    • Finish transitioning druntime's compiler interface from unchecked "magic" extern(C) functions to regular D (template) functions
    • Add context as the last parameter to each of druntime function that may need to allocate memory set it's default value to the global GC context. This is a pure refactoring, no change in behavior.
    • Add Scala implicit parameters to the language and mark the context parameters as implicit
April 20

GC is not the right model if you don't have the same ressources as Microsoft / Google / Oracle to invest massively on GC R&D, there is no way D can comepte with the latest Java's sub 1ms GC, no way

IMHO, Apple made the right decision to go with a RC with Swift, like they did with Obj-C

D's future is with memory ownership / reference counting

The more we stick to the GC, the more we'll have to play catchup with the competition

Even GO's GC is starting to become a negative amongst certain users https://blog.discord.com/why-discord-is-switching-from-go-to-rust-a190bbca2b1f

We need to transition to RC instead of GC, the sooner, the better

I know people like the GC, i do too, but in its current state it is absolute garbage when you compare to the competition

Again, the more we fill the STD library with GC code, the faster we'll get shadowed by the competition

April 20

It is very sad because it is the same discussion, every weeks, every months, every years

People agree that GC is trash, and yet no action done to improve things

I reiterate, i know i choose strong words, it's on purpose

D 3.0 needs to happen, with a GC-free features/std

That's the only way to be future proof and pragmatic

How many people who wrote the GC dependent std are still here using D? i bet close to 5%

They made D unusable for some workloads, and they made it dependent on very bad GC implementation, the wrong memory model when you advertise yourself as being a "system language"

D with core.stdc is the best version of D

Add traits/signature system and RC and you'll have a very capable and pragmatic system language

Simpler than to come up with 15151 different GC implementation with 2618518 different config options to waste months tweaking them cough JVM cough

April 20

And please note that i never said GC hinders the language adoption! because i never believed in that argument, it is a distraction from the real core issue, the memory model, when it is confusing, when it is not efficient, when it doesn't scale, at the end of the day, you'll have to pay for it

Being pragmatic about it like Swift and the issues related to scaling disappear "automagically", because you no longer depend on a Death Aura that could trigger at any time 'when allocating with new or via gc-dependent language features cough AA cough dynamic array cough exceptions cough asserts', blocking your whole world

April 20

And no, no @ could save us

@safe @system @pure @nogc @noreturn @help @nothrow void doSomethingForMePlease()
{
   writeln("is this where we want to go?");
}

April 20

C++ could have went with a GC, they decided to go against and encourage the use of smart pointers

That was smart, actually

April 20

On Tuesday, 20 April 2021 at 16:45:38 UTC, russhy wrote:

>

C++ could have went with a GC, they decided to go against and encourage the use of smart pointers

That was smart, actually

Well not that smart, but smarter then enforcing a GC into the language, because the std, even if trash, doesn't depend on anything, and gives you the option to supply an IAllocator almost all the time, zig does that too, and it is very nice

April 20

On Tuesday, 20 April 2021 at 16:44:01 UTC, russhy wrote:

>

And no, no @ could save us

@safe @system @pure @nogc @noreturn @help @nothrow void doSomethingForMePlease()
{
   writeln("is this where we want to go?");
}

Invalid @safe and @system contradict each other.
Also noreturn is not an annotation it's a type.
pure and nothrow are not annotations either they are keywords, though they arguably should be an annotations.

April 20

On Tuesday, 20 April 2021 at 17:08:17 UTC, russhy wrote:

>

On Tuesday, 20 April 2021 at 16:45:38 UTC, russhy wrote:

>

C++ could have went with a GC, they decided to go against and encourage the use of smart pointers

That was smart, actually

Well not that smart, but smarter then enforcing a GC into the language, because the std, even if trash, doesn't depend on anything, and gives you the option to supply an IAllocator almost all the time, zig does that too, and it is very nice

GC isn't real, it can't hurt you.

« First   ‹ Prev
1 2 3 4 5 6 7 8 9 10