Live data from Hacker News

The time the x86 emulator team found code so bad they fixed it during emulation

devblogs.microsoft.com

171–179 of 179 posts

Re: The time the x86 emulator team found code so bad they fixed it during emulation

#171

Earlier 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…

`rmdir /s /q` in a command prompt is significantly faster than Windows Explorer. 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.

Sure, my point wasn't that Windows Explorer is faster or slower compared to the command line or other OSes, but that deletion can be faster or slower (for Windows Explorer) depending on other factors too, like as per my example where it speeds up by 200% when I turn off that TortoiseGit option, which is nothing to scoff at.

Re: The time the x86 emulator team found code so bad they fixed it during emulation

#172
post #160

Earlier quoted context omitted.

>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).

Your dismissive tone implies you think I’m lying or something about my stated (and reproduceable) experience that deletions absolutely run a 1/3rd slower with certain software installed.

You gave an example of a third party program (TortoiseGit) slowing down deletion and implied Defender would also make it slower.

Im saying I have Win10 with everything ripped out, no defender, no logging, no tracelogging, no telemetry, zero filesystem filters/hooks. Delete speed is in the same ballpark as on freshly installed system.

Re: The time the x86 emulator team found code so bad they fixed it during emulation

#173

Earlier quoted context omitted.

> asking for 1 byte 65536 times, is indeed different than asking for 65536 bytes, 1 time. Yes it's different. As others have noted, the difference is what is returned if less than 65536 are available to read in the file: total failure vs partial read. There is, unsurprisingly, no requirement that it has an unnecessarily inefficient implementation to meet this behavioral requirement. (The C standard doesn't talk about…

Also you need to be careful what you read/write. In some cases. As many examples out there use int/char etc to show how to use the thing. But if you switch to structs that fwrite can totally burn you if you use the sizeof call. As the sizeof a struct can vary between platforms and compilers. Depending on packing. Then endianness can sometimes mess you up. If you are reading/writing for yourself you can get away with…

Are you sure you're not thinking of raw read() / write() (the operating systems calls) rather than fread() and fwrite() (the C standard library functions)? fread and fwrite already have a cache, so repeated calls won't make lots of OS calls.

Or, at least, they shouldn't! Clearly OP's implementation was a counterexample (it made lots of OS calls just for a single fread call).

Re: The time the x86 emulator team found code so bad they fixed it during emulation

#174

Earlier 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 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 .…

Shouldn't you be using cppreference.com instead of cplusplus.com? Because the former [0] actually has this language: 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/…

Maybe, but that text says “as if” and even “If an error occurs, the resulting value of the file position indicator for the stream is indeterminate. If a partial element is read, its value is indeterminate.” so it doesn’t in any way require implementations to implement it by actually reading one byte at a time.

That description also fits what I saw in the implementations I inspected, both of which simply try to read size × count bytes.

Re: The time the x86 emulator team found code so bad they fixed it during emulation

#175

Earlier quoted context omitted.

Shouldn't you be using cppreference.com instead of cplusplus.com? Because the former [0] actually has this language: 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/…

Maybe, but that text says “as if” and even “If an error occurs, the resulting value of the file position indicator for the stream is indeterminate. If a partial element is read, its value is indeterminate.” so it doesn’t in any way require implementations to implement it by actually reading one byte at a time. That description also fits what I saw in the implementations I inspected, both of which simply try to read s…

By the way, behold the original (from UNIX Version 7) stdio package [0]:

    fread(ptr, size, count, iop)
    unsigned size, count;
    register char *ptr;
    register FILE *iop;
    {
        register c;
        unsigned ndone, s;
    
        ndone = 0;
        if (size)
        for (; ndone= 0)
                    *ptr++ = c;
                else
                    return(ndone);
            } while (--s);
        }
        return(ndone);
    }
Thankfully, the definition of getc() [1] is indeed

    #define getc(p)  (--(p)->_cnt>=0? *(p)->_ptr++&0377:_filbuf(p))
Interestingly enough, because there is no explicit multiplication, this loop properly works on systems with e.g. 16-bit unsigned int but 32-bit pointers (and overflows just the same on systems where ints and pointers are the same size).

[0] https://github.com/v7unix/v7unix/blob/master/v7/usr/src/libc...

[1] https://github.com/v7unix/v7unix/blob/master/v7/usr/include/...

Re: The time the x86 emulator team found code so bad they fixed it during emulation

#176
post #57

Earlier quoted context omitted.

This is a horrible and yet not unexpected insight into the internals of Excel

To be fair this was Excell 25 years ago, may no longer be true. One of the other bugs (the Quark/ATM one) was also because of the programmers were worried about writing over stuff that hadn't been completely erased, the Quark guys wrote a string with 2 spaces at the end through a box that masked the end of the string, the ATM font renderer saw it couldn't fit the text so it split it in half and tried again so it drew…

Nowadays Excel is a webapp that reflows the entire DOM 400 times per keystroke!

Re: The time the x86 emulator team found code so bad they fixed it during emulation

#177

Earlier quoted context omitted.

Who's problem is this? Nvidia probably doesnt officially say anything about this and 99.9% of people do not rename process name

It's definitely Nvidia's problem if this breaks something. Nothing in the D3D/OpenGL specs says that you can (not) use certain executable names.

Yeah, I'm sure NVIDIA is going to get around to "fixing" a decade's old industry standard for something that contributes less than 10% of their revenue.

Re: The time the x86 emulator team found code so bad they fixed it during emulation

#178
post #122

Earlier quoted context omitted.

There's a good chance it was Excel's workaround for some other GPU's buggy behavior.

there were no GPUs at that time. What we were building in the late 80s/early 90s were the first generation of Mac graphics accelerators, really just glorified blit engines, a class of things that eventually grew into what we now call GPUs as people started to push CPUs into them

I see. I took "early/mid 90s" literally and thought you mean like 1991 through 1995, inclusive.

Re: The time the x86 emulator team found code so bad they fixed it during emulation

#179

Earlier quoted context omitted.

Also you need to be careful what you read/write. In some cases. As many examples out there use int/char etc to show how to use the thing. But if you switch to structs that fwrite can totally burn you if you use the sizeof call. As the sizeof a struct can vary between platforms and compilers. Depending on packing. Then endianness can sometimes mess you up. If you are reading/writing for yourself you can get away with…

Are you sure you're not thinking of raw read() / write() (the operating systems calls) rather than fread() and fwrite() (the C standard library functions)? fread and fwrite already have a cache, so repeated calls won't make lots of OS calls. Or, at least, they shouldn't! Clearly OP's implementation was a counterexample (it made lots of OS calls just for a single fread call).

Unfortunately not all of them. It depends on the device you are using, and the storage device, and the kernel, and the CRT you are using. The process I was using went from like 20-30 seconds to run to less than a second once I put a cache in front of it. Current implementations may have that cache. I would look first and see what they are doing. At the time I was working with about 6 different CRT's of varying age and quality. Some systems you can turn it on and off per device, or global, or per call depending on flags passed in. Really it comes down to reading the docs (probably right), and testing it out (empirical evnidence). That project I learned to not trust the c runtime libraries. But to verify what they are doing and re-read the docs and make sure I am even using the thing correctly vs what is written in the code and my assumptions.
Post reply on HN