833 karma · joined January 8, 2022
Even on a GPU, you wouldn't use an algorithm this simple in production. For small radii, leveraging bilinear filtering halves the number of samples. For larger radii, hierarchical pyramid approximations are popular.
Banking registers also weren't always readable, in which case either you'd need to shadow the banking register or avoid nested/interrupt scenarios.
I'd prefer 8086 segmentation any day over the headache of trying to execute 6502 code from a bank-switched cartridge with a single banking window and a write-only banking register.
If the FMA instruction syntax was designed for readability, then it would have used 4-argument syntax with a requirement for two registers to match instead of using the 1/2/3 encodings. But the reason why it uses those names instead is that it's more consistent with the instruction encoding and the format of most other vector instructions: the register/memory argument is last.
Similarly, x86 vector instructions that take an immediate byte cram a bunch of options into that byte, such as shuffle masks or operation options. The assembly syntax does not help constructing this byte at all. But that's because it's meant to map straightforwardly to the instruction encoding, not to be easy to manually read or write.
ARM assembly tends to be a bit more consistent, but has some similar quirks. The majority of ARM instructions are dst,src, but store instructions are reversed as src,dst so they have the memory argument second just like load instructions.
No one's saying it shouldn't exist, but it's a different story to ship software that requires it unconditionally, particularly if you are targeting the consumer market instead of only servers.
Not sure why you keep referring to Skylake since Intel hasn't shipped a Skylake-based CPU in years, and the most problematic CPUs currently shipping that lack AVX-512 support are several architectural generations ahead of Skylake, for both the P-cores and E-cores.
> Good thing Intel hasn't shipped a viable consumer-level CPU in years either. What should never have happened is Intel removing AVX-512.
Agreed on not removing, but saying that Intel hasn't shipped a viable consumer-level CPU in years is silly. They still ship huge volumes of CPUs, especially in laptops where AMD is still underrepresented.
> At one point, Intel integrated graphics were literally the most common individual GPU in the Steam Hardware Survey - Intel HD 4000 held the #1 spot until the GTX 970 overtook it in late 2015. Does that mean developers shouldn't have targeted discrete GPUs either, just because most survey participants didn't have the hardware they wanted to target?
Targeting a discrete GPU is different than not supporting integrated GPUs at all, which would be analogous. And many games do have to support integrated graphics even if the performance is not great, precisely because they don't aim high enough in the market to be able to ignore iGPUs entirely.
I also mention the Steam Hardware Survey because it tends to overrepresent users with higher end rigs. If you look at the non-gaming market, the hardware level tends to be considerably worse, and as a result a lot of productivity programs still ship plain SSE2 as their baseline required target.
https://support.arm.com/documentation/uan0016/a/
This has detailed information on latencies and throughput, which are important when optimizing SIMD code. But ARM doesn't publish optimization guides for all their cores.
On top of that, the cores are often modified in significant ways. Snapdragon CPUs, for instance, have used modified Cortex cores in the past and can have performance differences from the original core.
To be fair, Intel's been slacking a lot on this too, not even bothering to update their own optimization guide for their latest cores. But that's made up for the community mining this information in great detail on sites like uops.info, and also being a lot less x86 cores to deal with. On the ARM side, there's practically not much analogous other than the Apple M1 microarchitecture analysis.
One result of this is that a fair amount of C code targeted at 68000 systems used short instead int everywhere, and then had to be subsequently updated for CPUs that preferred int32 to int16. Occasionally collateral damage can be seen from this in mysterious comments like "check if the buffer is too int."
The ARM-based CPU manufacturers make this worse by posting almost no low-level documentation for their CPUs. For basically any mainstream x86 CPU, it's trivial to find documentation listing what ISA level it supports and general execution widths and latencies for common operations. For the majority of ARM CPUs, there's absolutely nothing. ARM only has optimization guides for selected Cortex cores, and NVIDIA published info for their Olympus core. But execution details had to be reverse engineered for Apple M1, and there is nothing for Oryon. This is especially bad for in-order cores, which unfortunately is still relevant because new CPUs are still being shipped with in-order efficiency cores.
- It's potentially a performance change in every single function, especially ones that have sizable fixed-size buffers
- If you have regressions you have to spray [[indeterminate]] everywhere, because there is no coarser way of suppressing it.
- While the language says unrecognized attributes are ignored, compilers frequently warn on unrecognized attributes. Clang, for instance, currently warns on [[indeterminate]].
- There is no defined macro name for backwards compatibility.
Which means that libraries are going have to all declare their own macros for [[indeterminate]] and pepper their code with it.This was only true for ARMv7 NEON (32-bit). ARMv8 / AArch64 NEON is IEEE compliant.
This seems to be a typo in the docs, VS2022 is 17.x and still generates volatile metadata. VS2026 is 18.x.
Last time I tested it, the penalty in Prism for running x64 code without volatile metadata was ~25% on Snapdragon X.
ARM64EC code is essentially x64 code pre-translated to ARM64. It's built against the x64 emulation ABI conventions but runs directly as native ARM64 code. Translation thunking conventions allow for cross-calling between ARM64EC and emulated x64 code.
A lot of the OS libs are shipped in Windows 11 ARM as ARM64X, so they're hybrid ARM64EC+ARM64. x86 libs like MSVCRT.DLL do still seem to be compiled with volatile metadata. DUMPBIN /LOADCONFIG reveals if volatile metadata has been included.
01b2086a 8975e4 mov dword ptr [ebp-1Ch],esi
01b2086d db45e4 fild dword ptr [ebp-1Ch]
01b20870 d95de4 fstp dword ptr [ebp-1Ch]
01b20873 d945e4 fld dword ptr [ebp-1Ch]
01b20876 d80dcc08b201 fmul dword ptr ds:[1B208CCh]
01b2087c d95804 fstp dword ptr [eax+4]
And that should be with optimization enabled, I didn't start it from the debugger.But clearly it has some support for using SSE2 when available, because it does use it for zeroing memory:
01b20884 0f57c0 xorps xmm0,xmm0
01b20887 660fd607 movq mmword ptr [edi],xmm0
01b2088b 660fd64708 movq mmword ptr [edi+8],xmm0With x87, however, that causes extra overhead from loads and stores that's best avoided. Unused stack space can be used to cache frequently used variables, but as operations must use ST(0) as one parameter, FXCH instructions must be used to swap around variables. Matching the x87 stack state on entry and exit of the loop is tricky and compilers historically have had trouble doing it. Different FPUs also differed on the efficiency of FXCH so there were often situations where a particular arrangement would double the speed of a routine on one CPU model and halve it on another.
The other problem is that Wine has only implemented a minimal amount of the Direct2D API to get specific programs working that aren't heavy graphics programs. Two major omissions, the last time I looked, were that Wine's implementation does not support antialiasing at all, and its ArcTo() draws a line.