4 ms·
It was "fixed" in a microcode update by disabling the loop stream buffer (LSD) which is a special mode of operation for very small loops where the instruction d
by BeeOnRope 5y ago
It was "fixed" in a microcode update by disabling the loop stream buffer (LSD) which is a special mode of operation for very small loops where the instruction decoders and uop cache in the CPU are shut down and the loop runs directly out of a small cache*. Since the problem arose only when the LSD was being used, in combination with hyperthreading and high byte register use, this effectively avoids the problem.
Of course, disabling the LSD has some costs: CPUs use more power and some loops are slower (though some are faster). These updates are usually applied silently without user consent, so you might quite surprised to find out that after a reboot your computation kernel suddenly draws more power or has slowed down or sped up.
> Can an x86 program detect whether this update has been applied? Can a Linux process set a DONT_HYPERTHREAD_ME_BRO bit?
Yes. One way would be to check the microcode version (available in /proc/cpuinfo on Linux, among other places), since the version that introduced this fix is known.
Another way would be to run a small loop known to fit in the LSD and then check a performance counter event which counts uops delivered from the LSD, like lsd.uops. This counter is always zero when the LSD is disabled (or realistically you could just run any substantial code and check the counter since you always have some non-neglible portion of the uops coming from the LSD). This is how I check it from the command line in practice.
Finally, if you don't have easy access to the counters, you could create a loop that has a significant performance difference depending on whether it is coming from the LSD or not. For example, a loop that crosses a 32-byte boundary will run 2 or more cycles when using the decoder or uop cache, but could run in 1 cycle in the LSD. Timing such a loop would give you a strong indication about whether the LSD is enabled.
---
* Specifically, the cache used is not a dedicated one, but rather the IDQ (decoded instruction queue) is reused. This queue holds uops and is normally fed by the decoders or the uop cache on one end, and which feeds the allocation/rename engine on the other. In LSD mode, this queue stops being a queue and is instead used as a kind of cache with the loop operations "locked down" in the queue and just repeatedly replayed.
- kaladin-jasnah 5y agoDumb question, but why is it abbreviated as LS_D_ when it's spelled loop stream _b_uffer?
- CalChris 5y agoIt's actually spelled Loop Stream Detector and it dates to the Core 2 processor family which is circa 2006. The LSD is described in section 3.4.2.4 of the Intel Optimization Manual, Optimizing the Loop Stream Detector (LSD). AnandTech describes how it works. https://www.anandtech.com/show/2594/4 https://www.anandtech.com/show/2594/4