lobsters score: 1 · tags: hardware
(Edit: I missed the footnote that touched on the Mx but didn’t include an actual reference that address the innacuracy of the 7% perf cost )
It’s weird that this talks almost entirely in terms of hypotheticals: it only has a footnote on direct comparisons, multiple studies have directly measured the cost of TSO on the Mx series of chips where TSO is runtime configurable. The most thorough that I recall was this one: https://dl.acm.org/doi/pdf/10.1145/3779212.3790129?download=true
Rather than just comparing perf and making claims it actually investigates whether the deltas are an inherent requirement of TSO or an engineering artifact. This addresses the issues of correctness of perf measurements that the post is referring to (the quoted 7% hit). That paper found that even discounting implementation problems there was still a fundamental cost of more than 3%, and of course none of these studies can investigate the complexity cost of the implementation itself (eg additional design complexity, area, power usage, etc) just the wall clock performance.
score 3 · canonical
My key takeaway from that paper, in terms of something useful that programmers can do without waiting on hardware engineers to do more magic, is this change that helped a few of the benchmarks (and which is a classic technique for making better use of cache set associativity):
Motivated by the above results, we rerun the outlier SPEC CPU benchmark while making large (> page size) dynamically-allocated buffers start at random intra-page offsets (in cache-line granularity). Figure 7 shows how this allocation policy eliminates the outlier TSO slowdowns, in both single- and multi-core executions. (Also shown is nab, whose single-core TSO slowdown is reduced from 6.6% to 4.1% due to this pol-icy.) In addition, this policy also improves execution time in Arm mode-sometimes dramatically (e.g., by ~ 40% for cactuSSN). This is because the underutilization of the L1 cache that this policy alleviates is detrimental to performance regardless of the memory model.
The authors are strenuously arguing for TSO and trying to play down its costs:
With these code changes, the harmonic mean of application TSO slowdowns across the entire benchmark suite and single/multi-core run types decreases from 4.2% to 1.9%.
In addition, future in-depth root-cause analysis of the remaining > 1% TSO slowdowns is necessary to determine if they stem from the cumulative impact of the factors explored in this paper, or from other (possibly addressable) reasons, such as atomic RMW operations and memory barriers.
score 1 · canonical
The authors are strenuously arguing for TSO and trying to play down its costs:
Yeah, it’s kind of classic “I find this thing annoying to deal with, so I’m ok with taking the cost, while ignoring that it means everyone else has to take that cost as well” (cost is not necessarily perf, it can be anything).
The problem with this argument (“the TSO cost isn’t as bad as we think, the Apple implementation isn’t going to be as optimized as intels so should be ignored”*, “the only cost is performance, there’s obviously no power or opportunity cost, etc”) is that it presumes the benefit is also more than it is - TSO on x86 doesn’t magically prevent all memory update issues, and if you think it does you’ve probably got subtle errors in your code.
IIRC intel also has non-TSO load/stores now as well despite their hypothetically sufficiently optimized TSO implementation.
* the papers on Apple’s TSO implementation pointed out a few bugs where the perf was unnecessarily terrible - which this post does point to as invalidating the comparison - but the paper doing this also said: fixed in newer hardware, and if you ignored those bugs and only looked at the correctly implemented portions the hit was still 3-4%. Yet this is still just waved away.
Again, this post is classic “I don’t care about this so everyone else should take the cost”. (See also: unsafe languages allow better performance! Except they mean every language, even safe ones have to take the cost of every mitigation: aslr, stack cookies, mte, pointer auth, … - e.g the “unsafe” perf win is more than consumed by the mitigations of that unsafety, and all the safe languages take that hit as well - I cover this in my eurollvm talk from a couple of months ago)
score 1 · canonical
I think the biggest group is the non-temporal load/store instructions - things like
movnti, etc. I think the majority are streaming instructions but I can’t for the life of me remember what they all - a small “all” - are, probably something likemovntps? essentially the original SSE load/store instructions withntstuck in the middle.I would assume avx has similar nt variants, but avx is well after the time I was directly futzing with this class of instruction, and I’ve been essentially arm only for most of the last decade so even the original SSE instructions aren’t something I can really recall from memory.
score 1 · canonical

