Intel disables Hardware Lock Elision on all current CPUs
git.kernel.org
git.kernel.org
Explicit TSX instructions are now merely opt-out, where previously they couldn't be disabled by the kernel. The posted patch doesn't seem to disable it but simply adds some of the bits needed to do so.
EDIT: Okay, I guess it is disabling Hardware Lock Elision (HLE), proper. But "hardware lock elision", lower case, implies all TSX-based lock elision code will stop being optimized. AFAIU RSX (explicit TSX) is usually only used for lock elision, anyhow; it's more of a microcode and speculation hack than a generic transactional memory feature, so the dividends quickly become elusive for anything beyond lock elision.
Disabling HLE makes the code still works because of the backward ISA compatibility... but you still lose the performance benefits of HLE.
Also, disabling it but still keeping it shown in CPUID...
Up to 20% for Array.Sort
[I'm reminded of the old Java "Vector" or "StringBuffer" that put a lock around every operation "because thread safety is good" which had high cost for single threaded usage. But this is likely not what this is about.]
However, part of the fix for JCC (https://www.intel.com/content/dam/support/us/en/documents/pr... ) to recover the performance loss will make other CPUs slower if separate executables aren't used for unaffected CPUs... which they won't.
> The MCU prevents jump instructions from being cached in the Decoded ICache when the jump instructions cross a 32-byte boundary or when they end on a 32-byte boundary. In this context, Jump Instructionsinclude all jumptypes: conditional jump (Jcc), macro-fusedop-Jcc(where opis one ofcmp, test, add, sub, and, inc, ordec), direct unconditional jump, indirect jump, direct/indirect call, and return
The workaround to lower perf loss of having jumps uncached when they are on a 32-byte boundary involves adding quite some nops... (or padding with meaningless prefixes)
Now maybe some people also like to elide some locks thanks to explicit RTM, but that's up to them, and that's not even completely hardware in this case (you have to write your own algo to do that and provide an explicit soft fallback), and of course Intel is not going to analyse algorithms to determine if there is logically some lock elision in a transnational section or not, and to only break out of speculation on the blocks of code presenting some...
Though, apparently Intel always disabled TSX on i3 processors for product segmentation, so maybe universal support was never in the cards...
I wish more CPUs would support at least a limited version of this. Basically, I want the equivalent of atomic<shared_ptr<T>>, but lock-free. That requires reading a pointer value from memory and then incrementing a reference count stored at that pointer, as a single atomic operation. I'm pretty sure that's doable with TSX, although I haven't actually tried it.
Transactional memory is hard!
I, too, wish TSX was more ubiquitous. I'm working on a kernel, and was hoping to use TSX to greatly simplify the logic of safely reading user memory from kernelspace - catching various exception cases without going through the real exception handler.
Turns out, none of the machines I have at my disposal have TSX - not my Desktop PC nor my server machine. So, RIP that plan, I guess.
What you want is absolutely doable with TSX. The overhead might be significant though. I wouldn't be surprised if locking a mutex was faster.
If you meant having an optimized codepath then that is doable. But given your writing a kernel there may be microarchitectural hazards that trigger excessive aborts.
I still think having a fast path using TSX could be useful, but since I never had a CPU with it, I never had a chance to benchmark it.
That’s what TSX is intended to be: a path that runs faster when possible.
The RPCS3 PS 3 emulator saw a 40% perf boost so some amazing gains are possible.
https://www.phoronix.com/scan.php?page=news_item&px=RPCS3-In...
You can do that without transactions with a lock cmpxchg16b instruction, or with a more complicated algorithm like this:
https://github.com/facebook/folly/blob/3de8f357eecaff89e3847...
Or is it just a matter of someone doing it?
I ran shellcheck to see if it was bash or sh and it didnt make a peep:). My Q is just asking if there is another similar quality tool. I see how you could interperit it the other way, thanks for asking.
bash is not POSIX-compliant. This script is.
https://www.gnu.org/software/bash/manual/html_node/Bash-POSI...
An x86-64 CPU boots in 16-bit real mode. An explicit option has to be used to switch it to 64-bit long mode.
That doesn’t mean that it’s not a 64-bit CPU.
$ echo I am posix compliant &>/dev/null
Similarly, not every Linux distribution puts bash in the same place, e.g. NixOS. So blindly putting `#!/bin/bash` as your shebang will result in a broken script on those systems.
You can just install bash or move it around to suit your script, but maybe you're shipping this script for other people to use and can't control their environments. It's easier to make a handful of changes to the script instead. This is why some people care about portability.
But the modern reason is https://en.wikipedia.org/wiki/Almquist_shell (ash) and its descendant, dash. Busybox environments ship with ash as the only available shell, unless you manually build another shell into the busybox chroot. As well, many initrd/initramfs environments have only one shell, usually dash. When scripting either of these, you have to write pure POSIX scripts.
And—mostly due to inertia—this tends to apply to all such environments, no matter their size. My Synology NAS (because it’s technically a busybox env) doesn’t have bash, despite having huge honking disks! Neither does CoreOS (because it’s technically a PXE initramfs env), despite not being intended as a “link-bandwidth-constrained” PXE environment at all. They’re just descended from these “lineages” of OSes that were used on more constrained devices in more constrained times, so their maintainers have kept to the old embedded-system ways.
On top of this, as the ash wiki article says, Debian made a choice to make dash their /bin/sh, and then forced all system scripts to use it, thus forcing them to be rewritten to be POSIX-compatible. (I think this was done with goal of lower memory-usage for constrained Debian environments that might still need to install some arbitrary subset of Debian system services.)
There was also another kind of pressure, 10-20 years ago, with Linux single-floppy or low-link-bandwidth PXE boot environments wanting to be as slim as possible, and therefore not shipping with bash.
I say this as somebody who has written shell scripts for almost 20 years.
Constructs like
if [ "X${str1}" = "X${str2}" ]
to avoid things exploding because a zero length variable might exist is a stupid and ugly hack.Not to mention the hell that is trying to use a user supplied filename safely in shellscript. (for the uninitiated, a unix filename can contain any character, and any sequence of bytes besides / and 0x00, including newlines, backspaces, shell meta-charachters and so many more exciting things)
That has less to do with POSIX compliance, as opposed to working around quirks with less-compliant historical implementations. Also, I think you'd have to dig pretty deep to find a test that doesn't support zero-length arguments; you'd be safe as long as you quote your variables.
The actual problem of ambiguity arises from variables that are also syntax, like '(', or '!', when using compound expressions (which you should avoid anyway).
# this is bad (also obsolete)
[ "$var" != foo -a "$var" != bar ]
# this is good (and fully POSIX compliant)
[ "$var" != foo ] && [ "$var" != bar ]
# you probably don't need to care for systems where this was necessary
[ "X$var" != Xfoo ] && [ "X$var" != Xbar ]https://www.phoronix.com/scan.php?page=article&item=spec-mel...
I think there are some further in-depth benchmarks with multiple generations of Intel and AMD, but can't find the link.
https://www.phoronix.com/scan.php?page=news_item&px=RPCS3-In... describes a 40% speedup for an emulation workload with TSX.
Do we know what the slowdown will be for current gen CPUs for various workloads?
This becomes wasteful when the number of functional units grows and not all bit combinations are reasonable. So the next reasonable thing to do is to introduce a lookup table from shorter coded instructions to the actual control bit patterns.
The CPU in this video adds an internal step counter that allows splitting an instruction over multiple cycles with a different control word for each cycle.
Modern CPUs are probably conceptually similar, but much more complex. Optimizations like pipelining and multiple ALUs make the whole decoding and checking process more complex and more dynamic.
It's the only reason I'm interested in RISC-V or advanced arm stuff. Even there's a metric fuckton more effort going into the latest Intel x86_64 chip, there's a lot of silicon left on the table.
Some board firmware loads updated microcode when it's updated. It has to be loaded at each boot by software in order to change.
- through BIOS updates (so the motherboard OEM has to release a BIOS update for that model that includes newer microcode and you'd have to download/apply the update)
- through the OS: both Linux and Windows can and do load ucode at boot, depending on the version/configuration/etc
This is how a good commit message should look like! Telling what, why and how something was fixed, instead of just "fixed X".
Or do we have two bugs being fixed at the same time?
Maybe it’s just been a long week...
From the article:
> The other TSX sub-feature, Hardware Lock Elision (HLE), is unconditionally disabled by the new microcode...
There is no reason to filter syscalls from some kind of bytecode with an interpreter run with full privileges if you simply run all of that unprivileged and you already have all syscall hardened and ACLed.
But for as long as there is a remotest possibility of a process being able to get around MMU, there is no reason to do that either.