Zeb Figura of CodeWeavers has proposed a Windows NT synchronization primitive driver to help performance of running games and applications designed for Windows on Linux with Wine / Proton.
As per the RFC (request for comments) posted onto the Linux kernel mailing list Figura notes: "This patch series introduces a new char misc driver, /dev/ntsync, which is used to implement Windows NT synchronization primitives."
Then giving some background on it: "The Wine project emulates the Windows API in user space. One particular part of
that API, namely the NT synchronization primitives, have historically been implemented via RPC to a dedicated "kernel" process. However, more recent applications use these APIs more strenuously, and the overhead of RPC has become a bottleneck.
The NT synchronization APIs are too complex to implement on top of existing primitives without sacrificing correctness. Certain operations, such as NtPulseEvent() or the "wait-for-all" mode of NtWaitForMultipleObjects(), require direct control over the underlying wait queue, and implementing a wait queue sufficiently robust for Wine in user space is not possible. This proposed driver, therefore, implements the problematic interfaces directly in the Linux kernel."
Figura did a presentation on it at the Linux Plumbers Conference in 2023 that you can see below:
Direct Link
What kind of performance difference might we see with something like this? The difference depends on your hardware and what you're trying to run but some FPS examples were given from multiple users including:
Game | Upstream | ntsync | improvement |
Anger Foot | 69 | 99 | 43% |
Call of Juarez | 99.8 | 224.1 | 125% |
Dirt 3 | 110.6 | 860.7 | 678% |
Forza Horizon 5 | 108 | 160 | 48% |
Lara Croft: Temple of Osiris | 141 | 326 | 131% |
Metro 2033 | 164.4 | 199.2 | 21% |
Resident Evil 2 | 26 | 77 | 196% |
The Crew | 26 | 51 | 96% |
Tiny Tina's Wonderlands | 130 | 360 | 177% |
Total War Saga: Troy | 109 | 146 | 34% |
What hardware and software each was tested on was not noted.
Some impressive numbers but again it's hardware dependent, but even so any performance uplift would be welcome, so hopefully the patch series gets some good comments and approval after any tweaks are done that may be needed. Looks like we could end up seeing a nice future performance improvement for Linux and Steam Deck gaming with Wine and Proton.
Source: Phoronix
Last edited by apprentix on 24 January 2024 at 11:58 am UTC
Thank God you guys exist!
Note that the improvements in the table is vs using the wineserver only so this is not compared with fsync or esync. Looks like the performance is similar to fsync/esync according to the presentation, just that some edge cases like Pulse Events and WaitOnAll now works while they are broken on fsync/esync.
Yeah, for Linux gamers the main benefit of this will be simply that things will finally be upstreamed. Those edge cases will barely matter for anyone.
Sounds like my Steam Deck is gonna have an easier time running some games.I can't wait to see these changes get added to the Linux kernel and SteamOS because if these numbers are any indication, it sounds like we're in for some awesome gaming experiences on the Steam Deck
I can't wait to see these changes get added to the Linux kernel and SteamOS because if these numbers are any indication, it sounds like we're in for some awesome gaming experiences on the Steam Deck
Steam Deck is already using fsync with corresponding kernel API, so it already benefits from better than wineserver approach. I.e. this ntsync isn't going to improve performance over esync or fsync if I understood correctly. It will just make it more formally correct for edge cases.
Last edited by Shmerl on 24 January 2024 at 4:34 pm UTC
Steam Deck is already using fsync with corresponding kernel API, so it already benefits from better than wineserver approach
To this point, most custom kernels (i.e. Tkg, Zen) already have fsync too! It is disabled for some games when Proton auto-detects them though, for example Yakuza 0 does not use fsync (uses option `nofsync`), but NieR:Automata does (you can check if a game is using esync/fsync and what options it has by inspecting the Proton log, enabled in launch options with PROTON_LOG=1).
Last edited by sonic2kk on 24 January 2024 at 4:52 pm UTC
To this point, most custom kernels (i.e. Tkg, Zen) already have fsync too! It is disabled for some games when Proton auto-detects them though, for example Yakuza 0 does not use fsync (uses option `nofsync`), but NieR:Automata does (you can check if a game is using esync/fsync and what options it has by inspecting the Proton log, enabled in launch options with PROTON_LOG=1).
You don't really need fsync anyway, since esync does mostly the same thing without the need for extra kernel interface. But still good to have a more formally correct approach that Wine can finally accept upstream.
Last edited by Shmerl on 24 January 2024 at 4:58 pm UTC
To this point, most custom kernels (i.e. Tkg, Zen) already have fsync too!Fsync was merged into upstream kernel a few years ago.
I watched the presentation and didn't really understood the point of it. Apparently, the only reason this gets picked over fsync is because a few methods that are not commonly used by Windows applications, especially the modern ones, cannot be emulated with fsync/esync. But if they're not commonly used, why not just leave them working through this old RPC mechanism?
Yes, that's right. It's more of a formality, but I suppose it's driven by Wine having such formal requirement - to correctly replicate Windows behavior in upstreamed code. And it was the reason neither esync nor fsync were accepted in Wine proper.
I wasn't clear why mixing things wasn't doable either, but I suppose it had some issue.
Last edited by Shmerl on 24 January 2024 at 7:21 pm UTC
It would be interesting to see a comparison between fsync and ntsync, my guess is there is little to no difference performance wise but I would love to be proved wrong.
I watched the presentation and didn't really understood the point of it. Apparently, the only reason this gets picked over fsync is because a few methods that are not commonly used by Windows applications, especially the modern ones, cannot be emulated with fsync/esync. But if they're not commonly used, why not just leave them working through this old RPC mechanism?
To this point, most custom kernels (i.e. Tkg, Zen) already have fsync too!Fsync was merged into upstream kernel a few years ago.
The reason you cannot have both is that you don't know at creation time if the object will later be used by those two api:s or not (one reason why the Wine dev thinks this whole Windows API stinks) so the wineserver must have control of all of the object in case any of them is every user for the WaitAll functionality and thus the whole fsync/esync route is no longer possible since that would lead to a split brain situation.
See more from me