256 KB of code to zero 64 KB of memory is the kind of optimization that makes you question every life choice that led to it.
The time the x86 emulator team found code so bad they fixed it during emulation
161–170 of 179 posts
Re: The time the x86 emulator team found code so bad they fixed it during emulation
#162Earlier quoted context omitted.
There are many, many, cases like this, including correctness fixes. One recent example I remember had a shader that computed: x = a / b * b The optimizer was allowed, but not obligated, to transform that into: x = a However, in this case, b was sometimes 0. And if so, the unoptimized version computed: x = a / 0 * 0 = Inf * 0 = NaN So badness ensued if the that particular path didn't get optimized, which could happen…
I'm curious, what's the ratio of: - deciding to inform the game developer & wait for reply vs not waiting for reply vs just fixing it yourself without informing the developer; and - if informed: developer actually fixing it vs only saying they would fix it vs no reply whatsoever (not counting automated "thank you for your inquiry" replies, in cases where you don't already have more direct channels to the dev than ema…
I'm not sure what fraction of devs actually fix things on their side, though. Once there's a driver workaround, and we've informed the devs, it's off our plate.
Performance is more of a gray area. We contact devs if there's something we can't work around, of course. And if there's something truly breaking. But for things that aren't exactly bugs, just things that could be improved, and we can improve on our own... well, we'll probably keep that for the competitive advantage.
Re: The time the x86 emulator team found code so bad they fixed it during emulation
#163Earlier quoted context omitted.
I've seen a lot of code that just assumes fread / fwrite succeeded without bothering to check the return value... But in this case if the code was calling fread 65536 times in a loop and getting 64KiB each time it wouldn't be good either! Sounds like the parent comment had to fix this with the internal cache thing to speed up the small freads. I think they meant the easy fix would have been swapping the args in the o…
There are no small freads in the story, whatever implements those freads supposedly split them up into many calls. But that sound more like a problem of that implementation than the fread callers as size == 1 is correct when you are reading a bag of bytes.
Re: The time the x86 emulator team found code so bad they fixed it during emulation
#164Earlier quoted context omitted.
I used to be a graphics card/chip architect for macs in the early/mid 90s - our chips were the fastest, but some programs were resistant because they did stupid stuff: pagemaker invalidated the font cache every time it went thru its main loop, quark with ATM did an n*2 thing every time it wrote text etc etc. We had special hardware to accelerate text drawing and it did nothing because the software pissed it away. We…
In my 68K Mac emulator running on modern (or even decade-old) hardware, performance in the traditional sense is less of a concern, but other issues arise. The big ones include CPU-burning loops that wait for a length of time or for an interrupt-decremented counter to reach zero, as well as invalid memory accesses (which I've made crash — no NULL deref for you). > We considered creating a plugin that fixed all these t…
I also worked on the original A/UX port for the Mac II, some hardware (like the IWM) required tiny buzzy loops, we ran into one bug where using the floppy caused ADB to freeze, but only on the release machines, not the prototypes all our engineers had, turned out there was hardware that made access to the VIA faster by pulling the clock in for 1 cycle, if you sat in a loop reading the timer in the via to measure a sector time for the IWM in too tight a loop it upped the output clock from the VIA to the ADB chip and over clocked it ....
Re: The time the x86 emulator team found code so bad they fixed it during emulation
#165Earlier quoted context omitted.
Its slowness is also a function of security software or any other file system "filters" (I believe they're called) are installed. For example, I run TortoiseGit which has a caching feature which is supposed to make it faster at showing what to commit. Disabling it increases the number of items I can delete per second in my Windows Explorer from about 1000 to about 3000 while making not making TortoiseGit operations m…
>slowness is also a function of security software or any other file system "filters" nah, its equally slow on system with everything ripped out (defender, filters, even logging).
Re: The time the x86 emulator team found code so bad they fixed it during emulation
#166Earlier quoted context omitted.
This is a horrible and yet not unexpected insight into the internals of Excel
There's a good chance it was Excel's workaround for some other GPU's buggy behavior.
Re: The time the x86 emulator team found code so bad they fixed it during emulation
#167Re: The time the x86 emulator team found code so bad they fixed it during emulation
#168Earlier quoted context omitted.
Is this why Windows takes so long to delete things?? Presumably those reads aren't done when using del from a console as that always seems a bit faster.
Its slowness is also a function of security software or any other file system "filters" (I believe they're called) are installed. For example, I run TortoiseGit which has a caching feature which is supposed to make it faster at showing what to commit. Disabling it increases the number of items I can delete per second in my Windows Explorer from about 1000 to about 3000 while making not making TortoiseGit operations m…
Yes C: is slow due to filters and Dev Drive is faster; but this difference can only be felt when using the command line; Windows Explorer has so much additional overhead that the overhead from file filters is insignificant in comparison.
Re: The time the x86 emulator team found code so bad they fixed it during emulation
#169Earlier quoted context omitted.
> Which basically expanded back in the day to 65k reads of 1 byte for several MB file. Each fread translated to 65k reads of ReadFile Windows API What software did that that badly? If the code asks for (up to) 65,536 single byte items, why would you split that into 65,536 calls? Also, that change changes behavior. The old call could read anything from zero to 65,536 bytes, the new one only can read zero or 65,536 byt…
The standard says that fread calls fgetc multiple times for each object: > For each object, size calls are made to the fgetc function and the results stored, in the order read, in an array of unsigned char exactly overlaying the object (wording unchanged since C99) If the file is unbuffered, depending on how the implementation handles buffering, and how it interprets the standard, then perhaps it does end up hitting…
>> For each object, size calls are made to the fgetc function and the results stored, in the order read, in an array of unsigned char exactly overlaying the object
Aha! That phrase led me to https://man7.org/linux/man-pages/man3/fread.3p.html. I consulted https://man7.org/linux/man-pages/man3/fread.3.html and https://man.openbsd.org/fread.3. Neither mentions that.
Now, I checked https://cplusplus.com/reference/cstdio/fread/. It doesn’t mention it, either.
⇒ this appears to be POSIX-specific.
Finally, if somebody implements fread as “For each object, size calls are made to the fgetc function”, it doesn’t matter whether you ask for 1 object of size 65,536 or 65,536 objects of size 1; both would call fgetc 65,536 times.
Re: The time the x86 emulator team found code so bad they fixed it during emulation
#170Earlier quoted context omitted.
The standard says that fread calls fgetc multiple times for each object: > For each object, size calls are made to the fgetc function and the results stored, in the order read, in an array of unsigned char exactly overlaying the object (wording unchanged since C99) If the file is unbuffered, depending on how the implementation handles buffering, and how it interprets the standard, then perhaps it does end up hitting…
> The standard says that fread calls fgetc multiple times for each object: >> For each object, size calls are made to the fgetc function and the results stored, in the order read, in an array of unsigned char exactly overlaying the object Aha! That phrase led me to https://man7.org/linux/man-pages/man3/fread.3p.html . I consulted https://man7.org/linux/man-pages/man3/fread.3.html and https://man.openbsd.org/fread.3 .…
Reads up to "count" objects into the array "buffer" from the given input stream "stream"
as if by calling fgetc "size" times for each object, and storing the results, in the order
obtained, into the successive positions of buffer, which is reinterpreted as an array of
"unsigned char".
This whole fread/fwrite's interface is hailing from the time where some OSes used record-based filesystems and were literally unable to read/write less than a record at a time.