Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What is the ref-code in the Playground examples, if C/C++ were supposed to not have GC? #155

Closed
mavavilj opened this issue Apr 5, 2024 · 23 comments
Assignees
Labels
documentation Improvements or additions to documentation question Further information is requested

Comments

@mavavilj
Copy link

mavavilj commented Apr 5, 2024

In https://github.com/fusionlanguage/fut/blob/master/doc/reference.md

it says that:

"Memory management is native to the target language. A garbage collector will be used if available in the target language. Otherwise (in C and C++), objects and arrays are allocated on the stack for maximum performance or on the heap for extra flexibility. Heap allocations use C++ smart pointers."

and the document or the repository don't seem to have any documentation regarding the ref-code (such as refCount).

However, in the Playground example https://fusion-lang.org/#ray one can see that the C code contains some parts that do something with references. Such as:

typedef void (*FuMethodPtr)(void *);
typedef struct {
	size_t count;
	size_t unitSize;
	size_t refCount;
	FuMethodPtr destructor;
} FuShared;

What are these references in the Playground code, if not some sort of GC?

@mavavilj
Copy link
Author

mavavilj commented Apr 5, 2024

This is GLib right, and it doesn't do garbage collection?

@mavavilj
Copy link
Author

mavavilj commented Apr 5, 2024

OTOH, I don't understand why the C couldn't be generated using just C. Or by adding a C API to the C++?

https://amontalenti.com/2006/04/04/using-c-instead-of-gobjectc

@pfusik pfusik self-assigned this Apr 5, 2024
@pfusik
Copy link
Collaborator

pfusik commented Apr 5, 2024

In C, heap allocations are done with reference counting, much like C++ std::shared_ptr. I will explain it in the documentation, thanks for pointing that out!

It's disputable whether reference counting is considered a form of garbage collection or not.

This has nothing to do with GObject. fut never emits any GObject code. GLib is only used for collections. Fusion projects which don't use these collections have no dependency on GLib.

@mavavilj
Copy link
Author

mavavilj commented Apr 5, 2024

The one possible problem with this for some users will be, whether the resulting code is as efficient as manually managed.

@pfusik
Copy link
Collaborator

pfusik commented Apr 5, 2024

A malloc/free is hundreds of instructions each. Reference counting adds very little overhead on top of that, like five instructions or so.

If you are concerned about high performance in C, use object/array storage instead of heap allocations.

@pfusik pfusik added documentation Improvements or additions to documentation question Further information is requested labels Apr 5, 2024
@pfusik
Copy link
Collaborator

pfusik commented Apr 5, 2024

I'd love to see the actual source code for these benchmarks.

@mavavilj
Copy link
Author

mavavilj commented Apr 5, 2024

I just picked them from image search. There's a lot more of that sorts of information though.

@pfusik
Copy link
Collaborator

pfusik commented Apr 5, 2024

Don't trust every chart you can find on the internet. :)

@pfusik
Copy link
Collaborator

pfusik commented Apr 5, 2024

https://blog.quasar.ai/2009/08/31/smart-pointers-are-overused

The "source code here" link is dead.

https://www.modernescpp.com/index.php/memory-and-performance-overhead-of-smart-pointer/

This is a synthetic test that deallocates the new allocation immediately.
My first thought was that any decent modern compiler would optimize the allocation entirely and indeed that's the case for gcc and clang: https://godbolt.org/z/dTd7nxj46

@pfusik
Copy link
Collaborator

pfusik commented Apr 5, 2024

https://blog.quasar.ai/hubfs/Imported_Blog_Media/smart_pointers-2.png from
https://blog.quasar.ai/2009/08/31/smart-pointers-are-overused

Now it works. This is a 2009 article that does not even mention std::make_shared. fut always emits std::make_shared and its C equivalent. The article uses std::shared_ptr<T>(new T()) which creates two separate memory allocations.

@pfusik
Copy link
Collaborator

pfusik commented Apr 5, 2024

Also, at a glance the "benchmark" seems to be bottlenecked by passing shared pointers by value. In Fusion you can pass them via non-dynamic references, which translate to raw pointers.

In short: that's an article that predates reference counting in the C++ standard (std::shared_ptr appeared in C++11) and makes a point about abusing shared pointers, not any performance problem when used correctly.

@mavavilj
Copy link
Author

mavavilj commented Apr 5, 2024

So can you find some more realistic benchmarks to describe the overhead in Fusion C/C++?

@pfusik
Copy link
Collaborator

pfusik commented Apr 5, 2024

What overhead do you mean? fut adds very little code on itself. I rewrote my projects from C to Fusion and they run just as fast.

@mavavilj
Copy link
Author

mavavilj commented Apr 5, 2024

What overhead do you mean? fut adds very little code on itself. I rewrote my projects from C to Fusion and they run just as fast.

So you measured latencies in allocations/deallocations too and such?

I asked about the ref-code, because I am not sure what it does, but it sounded like it requires or does some sorts of "check if refCount is zero" etc.

@pfusik
Copy link
Collaborator

pfusik commented Apr 5, 2024

The best way to avoid performance problems with dynamic allocations is to limit them or avoid entirely.

Dynamic allocations are heavy. Cache misses are heavy. Reference counting is very lightweight compared to these two.

@mavavilj
Copy link
Author

mavavilj commented Apr 5, 2024

@mavavilj
Copy link
Author

mavavilj commented Apr 5, 2024

In Haxe chat they suggested that in Haxe shared_ptr is replaceable by Ptr and Var.

So what about here then?

@mavavilj
Copy link
Author

mavavilj commented Apr 5, 2024

In particular, I find that:

https://github.com/fusionlanguage/fut/blob/master/doc/reference.md

is a bit slim on information regarding read-only and read-write references that are supposed to be the equivalent of raw pointers in C/C++.

@pfusik
Copy link
Collaborator

pfusik commented Apr 10, 2024

In particular, I find that:

https://github.com/fusionlanguage/fut/blob/master/doc/reference.md

is a bit slim on information regarding read-only and read-write references that are supposed to be the equivalent of raw pointers in C/C++.

What do you mean? It says:

Read-only and read-write references translate to raw pointers in C and C++

@pfusik
Copy link
Collaborator

pfusik commented Apr 10, 2024

In Haxe chat they suggested that in Haxe shared_ptr is replaceable by Ptr and Var.

So what about here then?

I don't know Haxe.

In my Fusion projects, most references are read-only and read-write references, which directly translate to raw C and C++ pointers. The objects are usually created as storage, which translates to stack variables, optimal for C and C++.

@pfusik pfusik closed this as completed Apr 11, 2024
@mavavilj
Copy link
Author

Read-only and read-write references translate to raw pointers in C and C++

It's just that I didn't understand whether it's a direct correspondence, because I didn't understand what read-only and read-write mean in C/C++ pointers.

@pfusik
Copy link
Collaborator

pfusik commented Jun 13, 2024

@mavavilj You raised concerns about the emitted reference counting in C and C++.

Today I checked in changes 8ad1459 and 41fcbb3 that avoid it when the reference to the dynamic allocation is not shared. This means using std::unique_ptr in C++ and plain malloc/free in C. In C, it's currently limited to arrays of primitive types, but that already eliminates all FuShared occurrences in the RECOIL project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants