Oh, this is something I'm going to have to try. Excellent work!
I have to ask, since people who'd know will probably be here, what's the "ten thousand foot view" of Oberon today? I'm aware of the lineage from Pascal/Modula, and that it was a full OS written entirely in Oberon, sort of akin to a Smalltalk or Lisp machine image. What confuses me is the later work on Oberon seems to be something of a cross between a managed runtime like Java or dot net, and the Inferno OS, where it can both run hosted or "natively". Whenever I've skimmed the wikipedia or web pages I've been a bit confused.
Thanks. In contrast to Smalltalk or Lisp, Oberon is originally a native language, and the Oberon System originally was conceived as the native operating system of the Ceres computer used for teaching in the nineties at ETH Zurich. So there is no image as in Lisp or Smalltalk. Oberon lives on today in the form of various dialects and derivatives (such as my Oberon+ or Micron languages, see https://github.com/rochus-keller/oberon and https://github.com/rochus-keller/micron). There are indeed Oberon implementations which run on Java or ECMA 335 runtimes, which is possible due to the very restricted pointer handling and memory management of Oberon.
The "OS" (or rather "kernel") was actually the VM which was implemented in microcode and BCPL. The Smalltalk code within the image was completely abstracted away from the physical machine. In today's terms it was rather the "userland", not a full OS.
It's refreshing to see Oberon getting some love on the Pi. There’s a certain 'engineering elegance' in the Wirthian school of thought that we’ve largely lost in modern systems.
While working on a C++ vector engine optimized for 5M+ documents in very tight RAM (240MB), I often find myself looking back at how Oberon handled resource management. In an era where a 'hello world' app can pull in 100MB of dependencies, the idea of a full OS that is both human-readable and fits into a few megabytes is more relevant than ever.
Rochus, since you’ve worked on the IDE and the kernel: do you think the strictness of Oberon’s type system and its lean philosophy still offers a performance advantage for modern high-density data tasks, or is it primarily an educational 'ideal' at this point?
I don't know. Unfortunately we don't have an Oberon compiler doing similar optimization as e.g. GCC, so we can only speculate. I did measurements some time ago to compare a typical Oberon compiler on x86 with GCC and the performance was roughly equivalent to that of GCC without optimizations (see https://github.com/rochus-keller/Are-we-fast-yet/tree/main/O...). The C++ type system is also pretty strict, and on the other hand it's possible and even unavoidable in the Oberon system 3 to do pointer arithmetics and other things common in C behind the compiler's back (via the SYSTEM module features which are not even type safe). So the original Oberon syntax and semantics is likely not on the sweet spot of systems programming. With my Micron (i.e. Micro Oberon, see https://github.com/rochus-keller/micron/) language currently in development I try for one part to get closer to C in terms of features and performance, but with stricter type safety, and on the other hand it also supports high-level applications e.g. with a garbage collector; the availabiltiy of features is controlled via language levels which are selected on module level. This design can be regarded as a consequence of many years of studying/working with Wirth languages and the Oberon system.
There was a couple of PhD theses at ETH Zurich in the 90s on optimizations for Oberon, as well as SSA support. I haven't looked at your language yet, but depending on how advanced your compiler is, and how similar to Oberon, they might be worth looking up.
I'm only aware of Brandis’s thesis who did optimizations on a subset of Oberon for the PPC architecture. There was also a JIT compiler, but not particularly optimized. OP2 was the prevalent compiler and continued to be extended and used for AOS, and it wasn't optimizing. To really assess whether a given language can achieve higher performance than other languages due to its special design features, we should actually implement it on the same optimizing infrastructure as the other languages (e.g. LLVM) so that both implementations have the same chance to get out the maximum possible benefit. Otherwise there are always alternative explanations for performance differences.
It might have been Brandis' thesis I was primarily thinking about. Of the PhD theses at EHTz on Oberon, I'm also a big fan of Michael Franz' thesis on Semantic Dictionary Encoding, but that only touched on optimization potential as a sidenote. I'm certain there was at least one other paper on optimization, but it might not have been a PhD thesis...
I get the motivation for wanting to use LLVM, but personally I don't like it (and have the luxury of ignoring it since I only do compilers as a hobby...) and prefer to aim for self-hosting whenever I work on a language. But LLVM is of course a perfectly fine choice if your goal doesn't include self-hosting - you get a lot for free.
This paper has presented a study of a system that
provides code generation and continuous code optimization
as a central system service[…]
> Our results have shown that–because of the profiling
feedback loop–object code produced by continuous optimizations
is often of a higher quality than can be achieved
using static "off-line" compilation. Optimization at runtime,
if performed judiciously, can often surpass optimizations
performed at compile-time, independent of whether the
latter are guided by profiling information or not. Our
results have also given evidence that reoptimizing an
already running program in response to changes in user
behavior can give rise to real performance improvements.
Kistler, Thomas, and Michael Franz. "Continuous program optimization: Design and evaluation." IEEE Transactions on Computers 50, no. 6 (2002). <https://doi.org/10.1109/12.931893>
I don’t like LLVM either, because its size and complexity are simply spiraling out of control, and especially because I consider the IR to be a total design failure. If I use LLVM at all, it would be version 4.0.1 or 3.4 at most. But it is the standard, especially if you want to run tests related to the question the fellow asked above. The alternative would be to build a frontend for GCC, but that is no less complex or time-consuming (and ultimately, you’re still dependent on binutils). However, C on LLVM or GCC should probably be considered the “upper bound” when it comes to how well a program can be optimized, and thus the benchmark for any performance measurement.
That benchmark is a great data point, thanks for sharing. The performance parity with unoptimized GCC makes sense, given how much heavy lifting modern LLVM/GCC backends do for C++.
Your approach with Micron and the 'language levels' is particularly interesting. One of the biggest hurdles I face in C++ with these high-density vector tasks is exactly that: balancing the raw 'unsafe' pointer arithmetic needed for SIMD and custom memory layouts with the safety needed for the rest of the application.
Having those features controlled at the module level (like your Micron levels) sounds like a much cleaner architectural 'contract' than the scattered unsafe blocks or reinterpret_cast mess we often deal with in systems programming. I'll definitely keep an eye on the Micron repository—bridging that gap between Wirth-style safety and C-level performance is something the industry is still clearly struggling with (even with Rust's rise).
I was about 5 links deep before I figured out what Oberon actually was. A high-level explainer at the top of the readme would be really nice for folks who aren't already familiar with the Oberon ecosystem
Spotting similarities betwen the appearance of the Oberon System and Plan 9, or Oberon syntax bits that were used in later languages, is left as an exercise for the reader.
This is great, especially being System 3, given the nice user experience Oberon eventually morphed into.
In System 3 with the Gadgets system it was already starting to feel like a proper mainstream OS, instead of the plain black and white, without framework like experience from the initial Project Oberon, even thought it was a technological achivement already, with a memory safe systems language.
I prefer the path taken down by Active Oberon, however that doesn't seem to also get that much love nowadays, and is much more complex to explore than System 3.
For those that not know it, it already had something like OLE (inspired by how Xerox PARC did it with Cedar), an AOT/JIT compilation system (with slim binaries for portability), and everything on a memory safe systems language.
Impressive work. Native boot on Raspberry Pi without emulation is a rare thing to see working cleanly. How's the performance compared to running Oberon on a standard x86 setup? And does this open up the possibility of running it headless as a small server?
114 comments
I have to ask, since people who'd know will probably be here, what's the "ten thousand foot view" of Oberon today? I'm aware of the lineage from Pascal/Modula, and that it was a full OS written entirely in Oberon, sort of akin to a Smalltalk or Lisp machine image. What confuses me is the later work on Oberon seems to be something of a cross between a managed runtime like Java or dot net, and the Inferno OS, where it can both run hosted or "natively". Whenever I've skimmed the wikipedia or web pages I've been a bit confused.
While working on a C++ vector engine optimized for 5M+ documents in very tight RAM (240MB), I often find myself looking back at how Oberon handled resource management. In an era where a 'hello world' app can pull in 100MB of dependencies, the idea of a full OS that is both human-readable and fits into a few megabytes is more relevant than ever.
Rochus, since you’ve worked on the IDE and the kernel: do you think the strictness of Oberon’s type system and its lean philosophy still offers a performance advantage for modern high-density data tasks, or is it primarily an educational 'ideal' at this point?
I get the motivation for wanting to use LLVM, but personally I don't like it (and have the luxury of ignoring it since I only do compilers as a hobby...) and prefer to aim for self-hosting whenever I work on a language. But LLVM is of course a perfectly fine choice if your goal doesn't include self-hosting - you get a lot for free.
>
This paper has presented a study of a system that provides code generation and continuous code optimization as a central system service[…]> Our results have shown that–because of the profiling feedback loop–object code produced by continuous optimizations is often of a higher quality than can be achieved using static "off-line" compilation. Optimization at runtime, if performed judiciously, can often surpass optimizations performed at compile-time, independent of whether the latter are guided by profiling information or not. Our results have also given evidence that reoptimizing an already running program in response to changes in user behavior can give rise to real performance improvements.
Kistler, Thomas, and Michael Franz. "Continuous program optimization: Design and evaluation." IEEE Transactions on Computers 50, no. 6 (2002). <https://doi.org/10.1109/12.931893>
Your approach with Micron and the 'language levels' is particularly interesting. One of the biggest hurdles I face in C++ with these high-density vector tasks is exactly that: balancing the raw 'unsafe' pointer arithmetic needed for SIMD and custom memory layouts with the safety needed for the rest of the application.
Having those features controlled at the module level (like your Micron levels) sounds like a much cleaner architectural 'contract' than the scattered unsafe blocks or reinterpret_cast mess we often deal with in systems programming. I'll definitely keep an eye on the Micron repository—bridging that gap between Wirth-style safety and C-level performance is something the industry is still clearly struggling with (even with Rust's rise).
Oberon is a very nice, fun and cozy system and environment for programming. I lived in it for a few months back around 2010 and it was a joy.
The Oberon language and the Oberon System were featured in Byte Magazine several times, most notably in Dick Pountain's articles:
https://vintageapple.org/byte/pdf/199103_Byte_Magazine_Vol_1... https://vintageapple.org/byte/pdf/199305_Byte_Magazine_Vol_1... https://vintageapple.org/byte/pdf/199501_Byte_Magazine_Vol_2...
Spotting similarities betwen the appearance of the Oberon System and Plan 9, or Oberon syntax bits that were used in later languages, is left as an exercise for the reader.
In System 3 with the Gadgets system it was already starting to feel like a proper mainstream OS, instead of the plain black and white, without framework like experience from the initial Project Oberon, even thought it was a technological achivement already, with a memory safe systems language.
I prefer the path taken down by Active Oberon, however that doesn't seem to also get that much love nowadays, and is much more complex to explore than System 3.
For those that not know it, it already had something like OLE (inspired by how Xerox PARC did it with Cedar), an AOT/JIT compilation system (with slim binaries for portability), and everything on a memory safe systems language.
Great Stuff!
Thanks to your work, that's about to change.
Thank you times a thousand <3