6 ms·
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. T
by ddevault 6y ago
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.
- faheywf 6y agoWhy 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-c-performance/ https://journal.stuffwithstuff.com/2009/01/03/debunking-c-vs...
- ddevault 6y agoBuilding 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.
- chrisoverzero 6y agoThe editor ate your links to the evidence. Can you repost them?
- lukevp 6y agoWhy 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-language/ https://mattwarren.org/2019/03/01/Is-CSharp-a-low-level-lang...
- bananaface 6y agoC# 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.
- striking 6y agoThere are a number of ways to control the GC in comfortable ways in C#. https://adamsitnik.com/Array-Pool/ 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.
- deleted 6y ago[deleted]
- JeanSebTr 6y agoYes. 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.
- deleted 6y ago[deleted]
- jerf 6y agoEmulation 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.
- jeroenhd 6y agoAs 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.
- ddevault 6y ago>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.
- banachtarski 6y agoC# 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.
- askingforproof 6y ago
- CJefferson 6y agoAre 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++.
- ddevault 6y agoqemu, 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.
- b0b_d0e 6y agoredream 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.
- wtetzner 6y ago> preferrably C Why?
- 1tCKV3QfIo 6y agoCniles don't want to invest in modern C++.
- ddevault 6y agoC++ is a bad programming language used by bad programmers to write bad programs. The only reason I mention it at all is because it can achieve the level of performance necessary for an emulator.
- VRay 6y agoEasy there, Linus
- saagarjha 6y agoYou can do better than that, Drew.
- brnt 6y agoPretty 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 ;)
- glouwbug 6y agoI 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++
- b0b_d0e 6y agoThe 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 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 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.