mirror of
https://github.com/yuzu-emu/yuzu-emu.github.io.git
synced 2025-07-27 12:11:56 +00:00
Update index.md
This commit is contained in:
parent
c2584fc39d
commit
57a46e1718
|
@ -70,19 +70,21 @@ Some games report the wrong device handle when sending vibration signals, like `
|
|||
|
||||
## Kernel Rewrites
|
||||
|
||||
This month has seen some important changes on yuzu’s kernel, with a focus on refactoring the code for thread management and synchronization. [bunnei](https://github.com/bunnei) started working on these changes two months ago, as covered on the previous progress report. Although they are a bit technical, these modifications are essential to emulate the Nintendo Switch accurately, and they also improve the quality of yuzu's code so it's easier to work for the devs.
|
||||
yuzu's kernel received important changes this month, focused on refactoring the code for thread management and synchronization. [bunnei](https://github.com/bunnei) started working on these changes two months ago, as covered on the previous progress report. Although a bit technical, these modifications are essential for accurate Nintendo Switch emulation. They also improve yuzu's code quality and make it easier to work with. There are still many changes planned for the kernel, so stay tuned for even more improvements in the very near future.
|
||||
|
||||
First on the list, we have a change to [ensure safe memory access for threads](https://github.com/yuzu-emu/yuzu/pull/5206). When multiple threads are running at the same time, there might be what is called a `Race Condition`: one thread modifies data that is currently being read by another thread, which could result in faulty or undefined behavior, since the second thread would be retrieving the wrong data or might even rewrite a different value, compromising the routine of the first thread. yuzu emulates the internal memory of the Nintendo Switch through a type of abstract data structure called `Page Table`, which works as a virtual layer between the physical and the emulated memory, by mapping these addresses in a "contiguous table" that can be easily accessed by the programmer without having to check where everything is stored in the real memory. Most of the code to manage operations related to memory were written before multicore CPU and asynchronous GPU were implemented, so naturally they didn't have any guard for memory-safe thread access. With this PR, bunnei introduced a lock that alleviates a race condition where the data in the memory pages was being accessed at the same time as the GPU was operating on them.
|
||||
First, there is an improvement to yuzu [ensuring safe memory access across threads](https://github.com/yuzu-emu/yuzu/pull/5206). A `Race Condition` happens when multiple threads are running simultaneously, and one thread modifies data while another thread accesses it. Race conditions can cause faulty or unexpected behaviour: a thread can retrieve partial data or even overwrite changes made by another. yuzu emulates the Nintendo Switch's internal memory using a type of abstract data structure called a `Page Table`, which works as a virtual layer between the physical and the emulated memory. It maps these addresses in a "contiguous table" that lets the programmer access memory easily without checking where actual memory stores everything. Most memory management operations were written before multicore CPU and asynchronous GPU were implemented. There was only a single thread back then, so there were no guards for thread-safe memory access. bunnei introduced a lock in this PR to alleviate a race condition where the data in the memory pages was being accessed while the GPU was operating on them.
|
||||
|
||||
bunnei has also been rewriting the [kernel scheduler](https://github.com/yuzu-emu/yuzu/pull/5131) based on `Mesosphere`, the kernel implementation of [Atmosphère](https://github.com/Atmosphere-NX/Atmosphere) (a custom firmware for the Nintendo Switch). Modern operating systems run many processes simultaneously while operational, however the CPU can only process one of them at any given time. The scheduler is an elemental piece of the kernel, as it is in charge of swapping CPU access to the different processes and choosing in which order this happens. As Atmosphère is intended to run in the hardware, all its components are properly reverse engineered, which ensures our scheduler will behave correctly too. This PR will facilitate porting other parts of Mesosphere in the future, too. This, in turn, will make yuzu's kernel match Horizon OS more closely. We all owe a big thank you to the people working on Atmosphère, as their reverse engineering efforts facilitate the work needed to implement these services in emulators.
|
||||
bunnei has also been rewriting the [kernel scheduler](https://github.com/yuzu-emu/yuzu/pull/5131) to be based on `Mesosphere`, the Nintendo Switch kernel reimplementation of [Atmosphère](https://github.com/Atmosphere-NX/Atmosphere) (the custom firmware for the Nintendo Switch we recommend in our dumping guide). Modern operating systems run many processes simultaneously, however, a single CPU core can only process one of them at any given time. The scheduler is an elemental piece of the kernel, as it is in charge of swapping CPU access to the different processes and choosing in which order this happens. As Atmosphère is intended to run on the hardware, all its components are properly reverse engineered, which ensures our scheduler will behave correctly too. This PR will also facilitate porting other parts of Mesosphere in the future. This, in turn, will make yuzu's kernel match Horizon OS more closely. We all owe a big thank you to the people working on Atmosphère, as their reverse engineering efforts facilitate the work needed to implement these services in emulators.
|
||||
|
||||
As a follow-up to this rewrite, bunnei reworked the way service calls were implemented in yuzu, by allocating their calls in their own [individual service threads](https://github.com/yuzu-emu/yuzu/pull/5208). There are many services running in the background on the Nintendo Switch, and they are in charge of initializing and managing specific tasks, such as audio, graphics, user input, networking, etc. yuzu emulates these services through HLE - High Level Emulation. This means that, instead of dumping the binary code of these routines from the Nintendo Switch and translating their instructions so that a PC can run them, the programmer reimplements the functionality of these services in C++. Thus, HLE works like a "black box": these services are called whenever there's a request from the games, and they send (or ask) for the corresponding data, even though internally they may be different to how the service was originally implemented in hardware. But, as long as the information requested or sent through the service is valid and processed appropriately, the system is being emulated correctly.
|
||||
As a follow-up to this rewrite, bunnei reworked the way service calls were implemented in yuzu, by allocating their calls in their own [individual service threads](https://github.com/yuzu-emu/yuzu/pull/5208). Many services are running in the background on the Nintendo Switch. They are in charge of initializing and managing specific tasks, such as audio, graphics, user input, networking, etc. yuzu emulates these services through HLE - High Level Emulation. This means that, instead of dumping the binary code of these routines from the Nintendo Switch and translating their instructions so that a PC can run them, the programmer reimplements the functionality of these services in C++. Thus, HLE works like a "black box": these services are called whenever there's a request from the games, and they send (or ask) for the corresponding data, even though internally they may be different to how the service was originally implemented in hardware. But, as long as the information requested or sent through the service is valid and processed appropriately, the system is being emulated correctly.
|
||||
|
||||
These service processes are independent of each other, so they are called asynchronously by games. But, prior to this PR, they were all being processed in the `CoreTiming` thread -- a thread that is used to process events at certain times in the future (for example, when a frame completes rendering). This meant that these processes would be called by games but they would not be processed until the `CoreTiming` thread was run, which resulted in these requests piling up in a queue and possibly introducing lag if the queue wasn't emptied fast enough. Thanks to the changes in this PR, each of these processes was moved to their own thread and is processed more quickly. An immediate benefit of this change is that load times improve significantly, and input lag is also reduced. But another important perk is that this implementation is more accurate, as it resembles the behavior of services in the Nintendo Switch. GPU emulation also runs in its own thread now, which is synchronized on GPU pushes and flushes. This means that `async GPU` can be decoupled from multicore and these settings can now be toggled independently from each other.
|
||||
These service processes are independent of each other, so games call them asynchronously. But before this PR, all of these services were being processed in the `CoreTiming` thread -- a thread that is used to process events at certain times in the future (for example, when a frame completes rendering). This meant that games would call these processes, but they would not be processed until the `CoreTiming` thread was run, which resulted in these requests piling up in a queue and possibly introducing lag if the queue wasn't emptied fast enough.
|
||||
|
||||
Finally, as a continuation to the previous two PRs, comes the [rewrite of the kernel synchronization primitives](https://github.com/yuzu-emu/yuzu/pull/5266) based on their implementations in Mesosphere -- namely, `Synchronization Objects`, `Condition Variables` and `Address Arbiters`. An in-depth explanation of how these mechanisms work goes beyond the scope of this report, but essentially they are tools used by threads in different processes to communicate with each other and be synchronized properly. The major benefit of these changes is that a lot of code that was being carried over from Citra (and that required major workarounds to make it function properly with multicore) has been changed in favor of mechanisms more appropriate for how yuzu works, besides making it closer to how the `Horizon OS` of the Nintendo Switch works.
|
||||
Thanks to the changes in this PR, each of these processes was moved to their own thread and is processed more quickly. An immediate benefit of this change is that load times improve significantly, and input lag is also reduced. But another important perk is that this implementation is more accurate, as it resembles the behaviour of services in the Nintendo Switch. GPU emulation also runs on its own thread now, which is synchronized on GPU pushes and flushes. This means that `async GPU` can be decoupled from multicore and these settings can now be toggled independently from each other.
|
||||
|
||||
Going in hand with these synchronization changes, [epicboy](https://github.com/ameerj) introduced a PR to [incorporate a syncpoint manager for nvdec](https://github.com/yuzu-emu/yuzu/pull/5237). This utilizes the tools mentioned previously to implement a more accurate GPU-CPU synchronization mechanism, which is crucial to avoid race conditions when async operations are being performed by the emulator when decoding video.
|
||||
Finally, as a continuation to the previous two PRs, comes the [rewrite of the kernel synchronization primitives](https://github.com/yuzu-emu/yuzu/pull/5266) based on their implementations in Mesosphere -- namely, `Synchronization Objects`, `Condition Variables` and `Address Arbiters`. An in-depth explanation of how these mechanisms work goes beyond the scope of this report, but essentially they are tools used by threads in different processes to communicate with each other and be synchronized properly. The major benefit of these changes is that a lot of code that was being carried over from Citra (and that required major workarounds to make it function properly with multicore) has been changed in favour of mechanisms more appropriate for how yuzu works, besides making it closer to how the `Horizon OS` of the Nintendo Switch works.
|
||||
|
||||
Going in hand with these synchronization changes, [epicboy](https://github.com/ameerj) introduced a PR to [incorporate a syncpoint manager for nvdec](https://github.com/yuzu-emu/yuzu/pull/5237). This utilizes the tools mentioned previously to implement a more accurate GPU-CPU synchronization mechanism. It is crucial to avoid race conditions when async operations are being performed by the emulator when decoding a video.
|
||||
|
||||
## UI changes
|
||||
|
||||
|
|
Loading…
Reference in a new issue