Most active commenters
  • kragen(5)
  • pizlonator(4)
  • johncolanduoni(3)

←back to thread

597 points pizlonator | 11 comments | | HN request time: 0.003s | source | bottom
Show context
crawshaw ◴[] No.45134578[source]
It is great that Fil-C exists. This is the sort of technique that is very effective for real programs, but that developers are convinced does not work. Existence proofs cut through long circular arguments.
replies(2): >>45134840 #>>45135366 #
johncolanduoni ◴[] No.45134840[source]
What do the benchmarks look like? My main concern with this approach would be that the performance envelope would eliminate it for the use-cases where C/C++ are still popular. If throughput/latency/footprint are too similar to using Go or what have you, there end up being far fewer situations in which you would reach for it.
replies(1): >>45134852 #
pizlonator ◴[] No.45134852[source]
Some programs run as fast as normally. That's admittedly not super common, but it happens.

Some programs have a ~4x slowdown. That's also not super common, but it happens.

Most programs are somewhere in the middle.

> for the use-cases where C/C++ are still popular

This is a myth. 99% of the C/C++ code you are using right now is not perf sensitive. It's written in C or C++ because:

- That's what it was originally written in and nobody bothered to write a better version in any other language.

- The code depends on a C/C++ library and there doesn't exist a high quality binding for that library in any other language, which forces the dev to write code in C/C++.

- C/C++ provides the best level of abstraction (memory and syscalls) for the use case.

Great examples are things like shells and text editors, where the syscalls you want to use are exposed at the highest level of fidelity in libc and if you wrote your code in any other language you'd be constrained by that language's library's limited (and perpetually outdated) view of those syscalls.

replies(8): >>45134950 #>>45135063 #>>45135080 #>>45135102 #>>45135517 #>>45136755 #>>45137524 #>>45143638 #
johncolanduoni ◴[] No.45135102[source]
While there are certainly other reasons C/C++ get used in new projects, I think 99% not being performance or footprint sensitive is way overstating it. There's tons of embedded use cases where a GC is not going to fly just from a code size perspective, let alone latency. That's mostly where I've often seen C (not C++) for new programs. Also, if Chrome gets 2x slower I'll finally switch back to Firefox. That's tens of millions of lines of performance-sensitive C++ right there.

That actually brings up another question: how would trying to run a JIT like V8 inside Fil-C go? I assume there would have to be some bypass/exit before jumping to generated code - would there need to be other adjustments?

replies(7): >>45135144 #>>45135158 #>>45135395 #>>45135400 #>>45135515 #>>45136267 #>>45138618 #
kragen ◴[] No.45135144{4}[source]
Latency is the killer, I think. A GC can be on the order of 100 instructions.
replies(2): >>45135176 #>>45135412 #
1. pizlonator ◴[] No.45135176{5}[source]
It’s a concurrent GC. Latency won’t kill you

I’ll admit that if you are in the business of counting instructions then other things in Fil-C will kill you. Most of the overhead is from pointer chasing.

See https://fil-c.org/invisicaps

replies(3): >>45135323 #>>45135355 #>>45135870 #
2. kragen ◴[] No.45135323[source]
"Concurrent" doesn't usually mean "bounded in worst-case execution time", especially on a uniprocessor. Does it in this case?

InvisiCaps sound unbelievably amazing. Even CHERI hasn't managed to preserve pointer size.

replies(2): >>45136725 #>>45140094 #
3. johncolanduoni ◴[] No.45135355[source]
For embedded use cases, it can definitely kill you. Small microcontrollers frequently have constant IPC for a given instruction stream and you regularly see simple for loops get used for timing.
4. yvdriess ◴[] No.45135870[source]
There's tricks to improve the performance of pointer chasing on modern uarchs (cfr go's Greentea GC). You want to batch the address calculation/loading, deref/load and subsequent dependent ops like marking. Reorder buffers and load-store buffers are pretty big these days, so anything that breaks the addr->load->do dependency chain is a huge win, especially if there are any near that traverse loop.
5. gf000 ◴[] No.45136725[source]
> "Concurrent" doesn't usually mean "bounded in worst-case execution time"

Sure, though this is also true for ordinary serial code, with all the intricate interactions between the OS scheduler, different caches, filesystem, networking, etc.

replies(1): >>45136794 #
6. kragen ◴[] No.45136794{3}[source]
Usually when people care about worst-case execution time, they are running their code on a computer without caches and either no OS or an OS with a very simple, predictable scheduler. And they never access the filesystem (if there is one) or wait on the network (if there is one) in their WCET-constrained code.

Those are the environments that John upthread was talking about when he said:

> There's tons of embedded use cases where a GC is not going to fly just from a code size perspective, let alone latency. That's mostly where I've often seen C (not C++) for new programs.

But I've seen C++ there too.

If you're worried about the code size of a GC you probably don't have a filesystem.

replies(2): >>45137346 #>>45140130 #
7. gf000 ◴[] No.45137346{4}[source]
Well, there is a whole JVM implementation for hard real-time with a GC, that's used in avionics/military -- hard real time is a completely different story, slowness is not an issue here, you exchange fast execution for a promise of keeping a response time.

But I don't really think it's meaningful to bring that up as it is a niche of a niche. Soft-real time (which most people may end up touching, e.g. video games) are much more forgiving, see all the games running on Unity with a GC. An occasional frame drop won't cause an explosion here, and managed languages are more than fine.

replies(1): >>45137511 #
8. kragen ◴[] No.45137511{5}[source]
Are you talking about Ovm https://dl.acm.org/doi/10.1145/1324969.1324974 https://apps.dtic.mil/sti/citations/ADA456895? pizlonator (the Fil-C author) was one of Ovm's authors 17 years ago. I don't think it's in current use, but hopefully he'll correct me if I'm wrong. The RTSJ didn't require a real-time GC (and IIRC at the time it wasn't known how to write a hard-real-time GC without truly enormous overheads) and it didn't have a real-time GC at the time. Perhaps one has been added since then.

I don't agree that "it is a niche of a niche". There are probably 32× as many computers in your house running hard-real-time software as computers that aren't. Even Linux used to disable interrupts during IDE disk accesses!

9. pizlonator ◴[] No.45140094[source]
> "Concurrent" doesn't usually mean "bounded in worst-case execution time", especially on a uniprocessor. Does it in this case?

Meh. I was in the real time GC game for a while, when I was younger. Nobody agrees on what it really means to bound the worst case. If you're a flight software engineer, it means one thing. If you're a game developer, it means something else entirely. And if you're working on the audio stack specifically, it means yet another thing (somewhere in between game and flight).

So let me put it this way, using the game-audio-flight framework:

- Games: I bound worst case execution time, just assuming a fair enough OS scheduler, even on uniprocessor.

- Audio: I bound worst case execution time if you have multiple cores.

- Flight: I don't bound worst case execution time. Your plane crashes and everyone is dead

replies(1): >>45143570 #
10. pizlonator ◴[] No.45140130{4}[source]
Yeah totally, if you're in those kinds of environments, then I agree that a GC is a bad choice of tech.

I say that even though, as you noticed in another reply, I worked on research to try to make GC suitable for exactly those environments. I had some cool demos, and a lot of ideas in FUGC come from that. But I would not recommend you use GC in those environments!

There is a way to engineer Fil-C to not rely on GC. InvisiCaps would work with isoheaps (what those embedded dudes would just call "object pools"). So, if we wanted to make a Fil-C-for-flight-software then that's what it would look like, and honestly it might even be super cool

11. kragen ◴[] No.45143570{3}[source]
Haha, yeah, I know.