Which is probably why people fear it
So, for purpose of doing testing for DataRace (specifically investigating the sample plugins read-write test being very slow under Windows), but also for ambitious future projects (like Linux driver development for the Ajazz 820Pro and Moza R5), that probably will never actually start and definitly not finish, I set up a Windows VM on my main machine (well, at least another step towards disposing of my Windows 10 install).
Setting up a Windows 11 VM wasn’t quite a straight forward as I expected (idk how I am not expecting it, any time I do anything I run into 15 kilotons more problems).
I had already qemu manager installed from when I upgraded my main homelab server back in November 2023, deploying to VMs that would continue running my k3s cluster while the main server was offline. This had it’s own complications, but those stories ar for another day, but once I was able to get the cluster running again on the server without these temporary nodes I had not touched qemu again.
I did start by downloading the latest Windows 11 image (23H2) from Microsoft, then started setting up a VM in User Mode.
I changed my mind and deleted the VM and created a new one in the usual Qemu Session, except during delete I let it delete the drive volume as well as the Windows 11 iso, so I had to download it a second time (What a great start).
Now the new VM I gave 8 vCPU (because I have a R9 5900x, cores are plenty, but we will get back to this) and 16gb of RAM (because I have 64gb, that I have only used for one university assignment for calcuating the winning plays in the board game Mill), gave it 96gb of storage.
Perfect, lets boot!
Eh, no, here is where the fun begins, stuck in the weird UEFI Interactive Shell all of the sudden. First time seeing this, this was not an issue when booting Alpine, I checked the boot order, and in the Shell commands like shutdown
and reboot
not working, and it still returning to the shell when forcefully rebooting the VM...
Turns out all I needed to do is type exit
, and then I am given a boot manager to get to the Windows 11 disk.
Except now I had to face tpm requirement, which you might have noticed I hadn’t mentioned in the setup. So I tried to search for workarounds, nah, didn’t work, then tried adding an emulated TPM, and that failed with a "Unsupported Option Version 2.0". It also failed with the "Unsupported Option Version 1.2" when the other option was selected, and the Additional info was a cryptic Phyton stacktrace (imo Phyton stacktraces are worse then Java).
After looking for the error, finding nothing, and further through guides I was able to figure out that I was missing swtpm
. Nothing hinted this was the missing component or that I needed something installed for this option, but now it finally just added the TPM module and worked.
So now, after Windows 11 finally installed, I had to only bypass the login requirement by:
Shift + F10
oobe\bypassnro
into it, hit enter, it will rebootAnd once you are on the Desktop you can turn networking back on
One thing that afterwards worked smoothly was setting up a Fileshare, this required me only two download to programs under Windows (the guide I used here). It did however act slightly wonky when it came to compiling rust, it threw an error that it couldn’t canonicalize the path, and while a lot of crates somehow still compiled, mine definitly didn’t (Although it did still enable me to copy files into the VM easier).
Another thing I noticed way later, after I had done most things, is that Qemu default option of "Use Host-topology" for some reason converted my 8 vCores into 8 sockets with 1 core and 1 thread each, so Windows installed and ran on a single core/single thread configuration (as Home does not use more then one socket), so lagged like crazy.
Once I switched to manual, gave it 1 socket, 4 cores, 2 threads (so in total 4C8T, like a good old i7) it was finally a vaguely responsive Operating system. But it took me so long to realice, that I had solved further issues and already compiled DataRace multiple times and had found the cause of the bad timings.
After rambling about most things being not Windows issues, lets get to Windows issue:
DataRace builds into a couple components (lib
, launcher
and any plugins), using dynamic linking and a c-abi to connect the components. Usually rust uses static linking, where all dependencies are "compiled into" the binary, however to load plugins dynamicly, and them to be able to interact with the rest of the programm we have our lib
against which is linked. I am using the C-Application Binary Interface (ABI) not just to offer people to write plugins in any language that can generate C-ABI libaries (most compiled languages), but also because rust does not have a stable ABI.
To generate the required C headers (and then the rust symbols for linking to the library for the launcher
and sample_plugin
) the project uses cbindgen and bindgen, bindgen specifically requiring Clang.
Well, that is easy, for Windows just run winget install LLVM.LLVM
(god only knows why this is named this way), except this failed with Failed in attempting to update the source: winget
.
Okay, I stubled across this article, which all attempts in there failed (I didn’t try the last option of downloading and installing winget manually), but I did also try Windows updates, and after multiple hours and reboots it still failed with zero explanation.
Turns out, 23H2 ships with a broken winget install (Github issue), and you have to open the Microsoft store and install App installer
.
Extra fun is that searching for App installer turns up random junk related to installer Android Apps, you have to use the link, then let that open with the Microsoft store... App? Programm? Malware? Whatever you want to call it... and install from there. And remember from last chapter, I was effectively still running on a single core, the store basically hung itself (which is fascinating, as Firefox was working pretty alright).
But now winget
will finally actually install anything.
Only one thing standing in my way of a build:
Because the project consists out of multiple parts I use make
under Linux; and because I use it basically everywhere, having one command to rule it all and be able to add options for premade testing, module compiling, and running is just great, even though it can do so much more when used for it’s original purpose with C.
But make doesn’t work under Windows, so I made a powershell script that simply builds everything.
Except that can’t run, as per default no scripts can be run from powershell, you have to run Set-ExecutionPolicy RemoteSigned
(I set it to Unrestricted
) in an Admin instance of Powershell, and now I could build my project (barring the issues above with the shared folder, but after copying the files over onto C:\
I finally could do it).
So, It did then at the end of my most recent Metro:2033 Stream do the debugging work for the issue mentioned in the beginning: The slow timings.
Under Linux this simple test, where we start a timer, read a value from a property handle, write a new value, read this value, then stop the timer, takes 7-20us (microseconds, aka 1ms = 1000us). This is still slow, but even when writing all Telemetry values (excluding wheels), so about 40 values, I come back with similar numbers, so I think this is the limits of precision of rusts std::time::Instant::now()
.
But on Windows I got a wopping ~600us (and sometimes numbers as high as 900 or 1200us).
Now, for storing Properties DataRace uses Atomics (except for Strings, those are more complicated, using a RwLock
, but also an atomic that indicates if it was changed, but the sample_plugin
timer is for Ints, and rf2 data is mostly floats, with Strings only updated on Change). And while it can definitly be argued that I am overusing Atomics, it would be strange for Windows to have such horrendous performance with atomics (a necessity for Mutexs, RwLocks and Arcs to even work).
So using Notepad (Microsoft Notepad, the most cursed code editor ever) I made the read-write-read loop some 100 times, and (once I got the loop to actually loop) it took it a wopping 80,000us (80ms, the frametime at 60fps is 16ms for context), so this is even worse (as a single iteration took over 800us, )...
Switching the Ordering for the Atomics from Release-Aquire
to Relaxed
didn’t really change anything, but when I uncommented the log outputs from the reads suddenly I got 4us.
So to circle back to the title, every issue I had under Windows was related to the CLI:
Logging to Powershell is performance suicide
Powershell script is in general just pain, and there not being a replacement for make (at least my usage of make, obviously Windows has buildsystems for C) just doesn’t help.
...if people are scared of cli’s when coming over to Linux because Windows Cli expierence is just horrible.
"But what about your Grandma..." shuh, I am talking about enthusiasts, programmers, PC gamers; not Boomers/Gen Z who are overburdened when trying to comprehend folders in a filesystem.
Heck, one of the appeals of VS Code (for roughly the year that I used it as my Windows, then Linux editor) for me was the terminal Window at the bottom, allowing me to use it for projects with multiple targets (like assignments) or running my Ansible playbooks. Today I do use NeoVim as my editor, so most of my day I spend in the terminal, maybe with a couple pdf open, and probably looking at the Browser instead of actually doing my assignment. The terminal is my home, helped probably in part with my expierence with my Homelab (using ssh to remote into a server is just the best).
I mean, you can use tools like yt-dlp and ffmpeg under Windows too, there is quickbms.exe (which I thought was Windows only, but works under GNU\Linux too) for compression/decompression archives (especially from game files), programming languages and their compilers... but outside of gameserver (and not even all, god damn it rF2 with your stupid gui) that is basically it. Text editiors? Nah.
Part of the issue is also having to have the porgramm in the same folder (or close enough to path to) so you can execute it, as adding the install location to the path is cumbersome (while under Linux, anything installed by your package manager will simply be callable from everywhere). Even OS features are hard to use from CLI or not availbel at all.
Not to speak of pipping and using escape characters for recoloring and moving the cursor.
It ain’t helping that Windows has both Powershell and Cmd, under their pushes modernizing their system (even at the complete disregard of compatibility, like seen with TPM, Secure Boot, the 15 different Teams app that will be forked into 4 different apps & remerge).
I should probably properly sit down and assess the Cli situation under Windows, but I am also getting quite eepy, and typing while tired is quite a bad idea, as I make even more spelling misstakes, but I wanted to write a second blog post about my recent expierence with the Windows 11 VM.
Next stop is then I guess setting up Wireshark to sniff usb packets to learn about how those USB periparals work...
Or I finally start working on the SimRacing-Commons Plugin, that will provide Properties and abstractions for all Sims (like general telemetry like Speed, and then Leaderboard generation and scoring)...
Or advance the Dashboard rendering in the lib
...
Or start another side project, like always...