News for hackers. Stuff that matters.
Re:Emulating Nintendo Switch Games on Linux by ddevault on Friday July 24, 2020 @01:11PM (#23941944)
Of these two emulators, Ryujinx is almost certainly never going to achieve a good level of performance, because they chose to write it in C# of all languages. Take my advice: if you're going to write an emulator, do it in C or C++, preferrably C. Ryujinx is a mind bogglingly massive amount of wasted effort.
Re:Emulating Nintendo Switch Games on Linux by jeroenhd on Friday July 24, 2020 @01:31PM (#23942191)
As sibling comments indicate, the overhead of C# isn't what it used to be and certainly isn't comparable to other languages like Python/Ruby/PHP.

Of course, there's always performance left on the table when you write in a language like C# or Java (and even a little performance matters a lot when it comes to emulation), but the memory safety that C# can provide over C++ can save the developers a lot of debugging.

I think such an application can perform perfectly well in a hardware generation or two and until that point compatibility matters more than speed anyway; that's where ease of development will shine. Running an unplayable game well is not a very interesting project for end users.

When the project reaches significant compatibility, other emulators can take ideas from its code and port them to C/C++/Rust/assembly if they desire to do so.

Re:Emulating Nintendo Switch Games on Linux by banachtarski on Friday July 24, 2020 @03:11PM (#23943356)
C# is consistently a worse performer than most javascript runtimes currently, and it's not much better than Python, Ruby, and PHP.

It's not just that. Basic patterns in C# are known to have pathological performance problems (implicit boxing, implicit heap allocations) that you simply don't run into programming in C or C++. These are things that tank performance in day-to-day programming that do not show up in carefully tuned benchmarks.

Source: Helped profile lots of C# games (not IL2CPP with Unity, although that's pretty bad IMO as well), not pleased with what I saw.

Re:Emulating Nintendo Switch Games on Linux by askingforproof on Friday July 24, 2020 @05:29PM (#23944671)
> C# is consistently a worse performer than most javascript runtimes currently

This is a bold claim. Please provide evidence that the most current .NET implementation (.NET Core 3.1) is slower than any JavaScript implementation.

This doesn't pass the smell test since you're comparing an ahead-of-time statically typed approach to a dynamic scripting language, both of which have had highly tuned JIT implementations, both of which are using garbage collection. You can implement things poorly in C#, sure, but you're making a much stronger claim of consistently poor performance.

Saying 'dude trust me' is not a source.

Re:Emulating Nintendo Switch Games on Linux by hu3 on Saturday July 25, 2020 @01:24AM (#23947046)
Agreed. Take a look at https://www.techempower.com/benchmarks/#section=data-r19&hw=...

C# currently 1st place in this webserver benchmark. Ahead of C/C++/Go/Java/D.

No offense to JavaScript, I like it and it has its uses. But surely your OP is joking when saying JavaScript is faster than C#. Even after all the performance improvements that V8 received.

Re:Emulating Nintendo Switch Games on Linux by asveikau on Friday July 24, 2020 @07:18PM (#23945470)
At least C# has things like the struct keyword to prevent heap allocations for simple data structures. I don't know if recent Java has caught up with this, but it was one of the innovative features MS came up with for .NET to avoid unnecessary overhead.

I feel like it's possible to write careful C# for performance. It just won't be entirely idiomatic. Things like buffer re-use, ordinary techniques you'd need to apply manually for C and C++ in similar domains too.

Re:Emulating Nintendo Switch Games on Linux by to11mtm on Saturday July 25, 2020 @11:09AM (#23949744)
A large part of C#'s advancements are that additional abstractions have been added in .NET Core to make at least some of those concepts a bit more idiomatic, especially around passing segments of memory around.
Re:Emulating Nintendo Switch Games on Linux by ddevault on Friday July 24, 2020 @02:46PM (#23943128)
>Of course, there's always performance left on the table when you write in a language like C# or Java (and even a little performance matters a lot when it comes to emulation), but the memory safety that C# can provide over C++ can save the developers a lot of debugging.

It really doesn't matter how much headache it saves you in debugging. The problem simply cannot be solved at the required level of performance if you use C#.

>When the project reaches significant compatibility, other emulators can take ideas from its code and port them to C/C++/Rust/assembly if they desire to do so.

The only legitimate use of this project is as a research bed for future emulators, so I agree with you there.

Re:Emulating Nintendo Switch Games on Linux by lukevp on Friday July 24, 2020 @01:25PM (#23942105)
Why the hate on C#? Are you perhaps thinking of languages like Ruby and Python and grouping them into the same bucket as C#? This[0] shows an example of C# vs C++ having a 10% performance gap on ray tracing. There is also no reason that extremely performance sensitive parts couldn’t be rewritten in Rust or C or C++ and called from C# over a FFI.

[0]: https://mattwarren.org/2019/03/01/Is-CSharp-a-low-level-lang...

Re:Emulating Nintendo Switch Games on Linux by bananaface on Friday July 24, 2020 @01:50PM (#23942446)
C# is garbage collected. Even if the performance potential was as high to begin with (it's not), that's a non-starter for heavy games because you need to be able to control & predict the performance spikes that GC creates. That's even more important for an emulator, which needs more predictability than a regular game.
Re:Emulating Nintendo Switch Games on Linux by jerf on Friday July 24, 2020 @02:06PM (#23942650)
Emulation involves a lot of large byte arrays and static structs that your code updates a lot to represent the hardware. It isn't necessarily creating a ton of objects all the time. I do not have specifics on hand for these emulators but it's not hard to imagine that they could well be running the GC for a few microseconds every few minutes or something [1]. It is a very different type of program than a traditional game, or, indeed, almost any other kind of program.

There does seem to be this odd semi-subconscious idea in the "GCs aren't appropriate for any high-performance" world that they intrinsically work by stopping the world for 50ms several times per second or something, but that does not have to be the case.

[1]: I actually have a number of servers in Go that run on about this schedule. If you eliminated 100% of my GC cost for these servers, I wouldn't care at all, or even notice.

Re:Emulating Nintendo Switch Games on Linux by b0b_d0e on Friday July 24, 2020 @03:14PM (#23943372)
> Emulation involves a lot of large byte arrays and static structs that your code updates a lot to represent the hardware

Things work a bit differently for "modern" emulators, where the emulators recreate the kernel/OS at a high level. In these emulators, the games will call into the system, and the kernel will be expected to do all thats necessary for the call. In the high level approach, this means that if a call allocates, so does the emulator (edit: note that this is a simplified view, as both emulators map a 4GB page that they work in for the guest system memory, but theres still a ton of side allocations that happen "outside" of the guest kernel). There is a lot of work that goes on in this layer of emulation, and theres going to be objects that the emulator allocates and later destroys. Process tables, thread lists, scheduler information, timing events, kernel synchronization primitives like mutexs, and so on to name some. I'm not intimately familiar with Ryujinx to make any statements about how they handle GC of course, but its something that they'll need to take into consideration. That said, there's plenty of other things like JIT compilation, shader compilation, caches filling up, and on and on that all also cause micro stuttering, so its not uncommon for even C or C++ emulators to have annoying pauses too.

Re:Emulating Nintendo Switch Games on Linux by striking on Friday July 24, 2020 @01:55PM (#23942496)
There are a number of ways to control the GC in comfortable ways in C#. https://adamsitnik.com/Array-Pool/ comes to mind, especially for games. So you can lean into GC when possible, and switch to an unmanaged approach when you are seeing perf issues.
Re:Emulating Nintendo Switch Games on Linux by JeanSebTr on Friday July 24, 2020 @02:03PM (#23942609)
Yes. But C# also supports struct which are stack allocated.

C# allows to optimise memory allocation when that matters and to rely on the GC for less critical parts.

Re:Emulating Nintendo Switch Games on Linux by p1necone on Friday July 24, 2020 @09:02PM (#23946032)
Plenty of big games have been written in C# with XNA/Monogame. See this so thread for some examples: https://gamedev.stackexchange.com/questions/1667/what-are-so...
Re:Emulating Nintendo Switch Games on Linux by PuercoPop on Friday July 24, 2020 @09:28PM (#23946142)
> that's a non-starter for heavy games because you need to be able to control & predict the performance spikes that GC creates

Real-time garbage collectors are a thing. Maybe not common, but they have existed for at least 20+ years.

Re:Emulating Nintendo Switch Games on Linux by faheywf on Friday July 24, 2020 @01:22PM (#23942063)
Why are you so certain? It seems that even a decade ago C# performance wasn't far off from C++, if not slightly faster[0].

[0] https://journal.stuffwithstuff.com/2009/01/03/debunking-c-vs...

Re:Emulating Nintendo Switch Games on Linux by ddevault on Friday July 24, 2020 @02:44PM (#23943102)
Building contrived tests which "prove" the performance of C# in the face of mountains of evidence to the contrary is on a much different scale from emulating an entire complicated hardware system.
Re:Emulating Nintendo Switch Games on Linux by chrisoverzero on Friday July 24, 2020 @06:54PM (#23945317)
The editor ate your links to the evidence. Can you repost them?
Re:Emulating Nintendo Switch Games on Linux by b0b_d0e on Friday July 24, 2020 @02:51PM (#23943182)
The other sibling comments were talking about general C++ vs C# performance, but I wanna get into some emulation specific context here that's missing. I was one of the contributors to the yuzu project since it was first started, and so I'm fairly familiar with the challenges of switch emulation, albeit I'm not going to pretend like I was one of the all-star devs responsible for making the magic happen. (I've recently stopped contributing to the project in order to pursue other interests, so i'm going to keep the information here general and not specific in case somethings changed in the last month.)

Let's start off by breaking the core performance portions of emulation into a few broad categories. There's CPU emulation, for running the actual guest exe, Kernel and OS emulation for handling the system calls that games make, and GPU emulation for translating the guest's GPU work into modern graphics API that your PC can use. Now let's compare how language overhead will affect each of these main scopes.

CPU Emulation - Both yuzu and Ryujinx use JIT compilation to recompile the guest ARMv8 instructions into x64 at runtime. The specifics of the two emulators JITs are pretty different, and it'd be cool to go into more details, but the mile high view is a comparison of C# vs C++ isn't going to have much of an effect on the runtime difference. At least not near as much performance gap between techniques and optimization levels that the JIT is capable of. The goal of JIT compilation for CPU code is to remove as much interpreter overhead as possible, so if your choice of programming language is slowing down the JIT, that suggests that you have somewhere else to improve in the JIT ;)

Kernel/OS - This is the area that will have the largest performance difference between implementation languages, but with the major caveat that Kernel and OS emulation requires the least amount of processing power out of the 3 categories mentioned here. The Kernel and OS are responsible for managing and scheduling threads, handling network connections, and etc, but really most of these things have fairly low impact on final application performance in comparison to CPU and GPU emulation. As a side note, emulators aren't the only groups interested in switch OS/Kernel work. The open source Atmosphere custom firmware for the switch is working through recreating an open source kernel/os for the switch, and the two emulators benefit from their work too. (See the licensing exemptions here https://github.com/Atmosphere-NX/Atmosphere#licensing)

GPU Emulation - This is probably the trickiest part of Switch emulation, and once again, it comes down to how you emulate it, and not the language you use to write the emulator. The biggest performance differences between the GPU emulation of the two emulators will boil down to technique differences, and not the programming language. GPU emulation performance can be roughly broken into two parts, the "actual" gpu running time, and the state management/conversion. There's only so much an emulator can do about the actual GPU running time since at some level, you are going to need to run the game's GPU code, but the other half is a whole lotta code to avoid doing more work, and much of the GPU performance optimizations goes here. Things like managing the game's GPU memory, avoiding changing or querying GPU state unless necessary, converting nvidia shader ASM into SPIR-V or GLSL, and so on, are not generally going to be bottlenecked on the emulator's language of choice, but on the algorithms and designs that you use. Also a side note, the average comment about how "easy" switch emulation is because of "off the shelf nvidia parts" really misunderstands just how much work goes into this part. Switch emulation benefits greatly from the open source nvidia reverse engineering efforts from teams like nouveau, and others working on open source GPU acceleration on the switch like https://github.com/devkitPro/deko3d but also a great deal of effort from the switch emu devs themselves, writing tests cases to run on the switch to find edge cases and document behavior. It definitely is not easy work.

At the end of the day, every drop of performance counts, but some drops are much much larger than others. As such, the advantages of any language's performance characteristics will be heavily offset by the design choices the emulator uses. The creator of ryujinx is very comfortable with C#, and with good development practices, there's no intrinsic reason that one cannot achieve good performance in a C# emulator. And if one decides that it's worth the tradeoff to do some extra work for performance in exchange for a more comfortable development environment, then I say let them do what they want.

Shoutouts to both the yuzu and Ryujinx teams for all their hard work. I loved working on emulators a lot, and highly recommend anyone who's interested in contributing to give it a shot, its a really challenging and rewarding kind of project where there's always something new to learn about in a broad array of subjects.

Re:Emulating Nintendo Switch Games on Linux by CJefferson on Friday July 24, 2020 @01:37PM (#23942272)
Are any significant current emulators written in C?

The main emulators off the top of my head, MAME, bsnes (and the related higan) and dolphin, are all in C++.

Re:Emulating Nintendo Switch Games on Linux by b0b_d0e on Friday July 24, 2020 @01:58PM (#23942554)
redream is a Dreamcast emulator written in C only. libretro (the core API behind Retroarch) and Retroarch itself are primarily C. mupen64plus is in C, although the common 3rd party plugins and frontends are not always in C.
Re:Emulating Nintendo Switch Games on Linux by ddevault on Friday July 24, 2020 @02:40PM (#23943053)
qemu, a dozen gameboy emulators, dosbox, the 9front emulators (NES, SNES, GB, GBA, C64, 2600), xemu, z80e, and many, many more. Lots of the C++ emulators you're familiar with have the performance critical parts written in C as well, excepting some newer emulators which leverage something like LLVM for JIT emulation.
Re:Emulating Nintendo Switch Games on Linux by wtetzner on Friday July 24, 2020 @02:04PM (#23942624)
> preferrably C

Why?

Re:Emulating Nintendo Switch Games on Linux by glouwbug on Friday July 24, 2020 @07:13PM (#23945441)
I once spent 3 years on a C project and I realized it's strength is that it does not change. I didn't feel the need to rewrite it with latest features like one might with C++
[dead]
Re:Emulating Nintendo Switch Games on Linux by brnt on Saturday July 25, 2020 @07:53AM (#23948517)
Pretty much all (modern) HPC I'm aware of is C++. Now I'd be the first one to agree researchers aren't the best programmers, but I also think that is not the only thing that matters. C++ allows huge teams to cooperate in getting a lot of stuff done (there isn't a single CERN result that isn't verified against C++ generated data for instance).

C++ is like a natural language at this point: very crufty and layered, hard to use sometimes, even ugly, but you can do a ton with it and if you work with the language you can even write poetry in it ;)

Re:Emulating Nintendo Switch Games on Linux by saagarjha on Friday July 24, 2020 @04:50PM (#23944280)
You can do better than that, Drew.
Re:Emulating Nintendo Switch Games on Linux by VRay on Friday July 24, 2020 @03:17PM (#23943393)
Easy there, Linus