0

When I run the following code, I get ERMS == false, but erms == true. Why is this?

#include <intrin.h>
#include <Windows.h>

int main()
{
    int regs[4];
    __cpuidex(regs, 7, 0);
    // https://en.wikipedia.org/wiki/CPUID#EAX=7,_ECX=0:_Extended_Features
    bool erms = !!(regs[1] /* EBX */ & (1 << 9));
    bool ERMS = !!IsProcessorFeaturePresent(PF_ERMS_AVAILABLE);
}
user541686
  • 205,094
  • 128
  • 528
  • 886
  • Where is `PF_ERMS_AVAILABLE` coming from? I can't seem to find that in the SDK. – IInspectable Nov 02 '22 at 14:07
  • I'm going to guess [Because Intel says they are mostly pointless](https://stackoverflow.com/a/43574756) and thus there is no point trying to use ERMS (Enhanced REP MOVSB/STOSB) on modern CPUs. It's probably best to just use `memcpy` can let the compiler deal with it. Note that undocumented `PF_*` flags are not stable and may change between builds of the windows SDK. As that flag is not currently documented it may be removed in a later version. – Mgetz Nov 02 '22 at 14:17
  • Maybe it just requires updated Windows (Windows 11?) to be impletemented in `IsProcessorFeaturePresent` – dewaffled Nov 02 '22 at 14:19
  • @dewaffled ERMS is a feature from Ivy Bridge, it should be present in the Windows 8.1 SDK at the latest. So it shouldn't need Windows 11. But if you see the answer I linked it was of dubious benefit anyway. – Mgetz Nov 02 '22 at 14:20
  • @Mgetz I have `10.0.19041` SDK installed and the feature list ends on `#define PF_AVX512F_INSTRUCTIONS_AVAILABLE 41`. Google finds `#define PF_ERMS_AVAILABLE 42` only in [MingGW](https://www.mail-archive.com/mingw-w64-public@lists.sourceforge.net/msg18925.html) and Rust sources. Also there are no values 43 and 44 from the MinGW patch in the SDK I have. – dewaffled Nov 02 '22 at 14:39
  • @dewaffled interesting it is present in 10.0.22621 (I haven't bothered to bisect back) Not sure why MS would add it that late as even Intel seems to say it's a dubious feature unless someone is focusing all their perf on specific SKUs that are otherwise compromised. – Mgetz Nov 02 '22 at 14:59
  • Would someone with up-to-date Windows 11 mind corroborating what I'm seeing? @IInspectable: It's in the 10.0.22000.0 SDK. – user541686 Nov 03 '22 at 03:39
  • Oh, hm, Windows 11 then. Can't wait to never give that a try. – IInspectable Nov 03 '22 at 12:00
  • @user541686 tested this on my VS2022 and cannot replicate your results. I'm getting that it's supported from both on my rocket lake CPU. Is your application using a manifest that says it supports Windows 11? Because you may be hitting a compat shim. Windows 11 22H2 – Mgetz Nov 03 '22 at 13:34
  • @user541686 I am not able to reproduce on win11 in visual studio 2022 with 10.0.22000.0 sdk. `ERMS == true and erms == true`. Could you please tell us which version of system and visual studio are you using? – Jeaninez - MSFT Nov 04 '22 at 03:17
  • Thanks - I wonder if it's a Windows 10 thing? I'm on Win10 with VS2022 and my manifest supports up to Win10. – user541686 Nov 04 '22 at 03:26
  • @user541686 well that kinda makes sense, things that only show up in the Windows 11 SDK are likely to only work on Windows 11 . My guess is you're getting a fallback of what the method does with an unrecognized input. – Mgetz Nov 04 '22 at 13:11
  • @Mgetz: For something like this I would've thought system updates would've added support. – user541686 Nov 04 '22 at 23:52
  • @user541686 nope, not the way OS features work. Generally speaking Windows 10 should be considered "feature complete" if not for pushback MS wouldn't have brought DirectStorage or DX12 ultimate to it either. Smaller things like this would be considered stability risks. – Mgetz Nov 05 '22 at 14:29
  • @Mgetz: Interesting, thanks. I was thinking back to how they added AVX support to Windows 7 in SP1, but I guess saving/restoring registers is a bit different. – user541686 Nov 05 '22 at 15:50
  • @user541686 I test the code on win10 in visual studio 2022.The issue still cannot be reproduced. Result: `ERMS == false and erms == false` – Jeaninez - MSFT Nov 07 '22 at 09:20
  • @Jeaninez-MSFT: if `erms == false` then obviously `ERMS` would be `false` too. That just means your CPU doesn't support it. The question is what happens when `erms == true`. – user541686 Nov 07 '22 at 14:52
  • @user541686 if this feature is really make or break then you can go with a two step verification. Call `IsProcessorFeaturePresent` first as that avoids the issues with serialization and stalls that `cpuid` does AFAIK (because it should be cached). If that fails then you call `__cpuidex` just to be sure and take the perf hit. Otherwise you can just run with it because the perf isn't bad to assume it's there or just ignore it completely. – Mgetz Nov 07 '22 at 18:26
  • @Mgetz: Thankfully this particular feature is only a performance question rather than a capability question, so yes, it's not a big deal and I can deal with it or ignore it as you mention. I mainly needed to know whether this is a problem with my setup or whether Windows 11 and later might have issues too. In general, though, note that for some features you need *both* `IsProcessorFeaturePresent` *and* CPUID because, for example, Intel SDE only affects the latter, whereas some features require OS support as well. – user541686 Nov 08 '22 at 01:09

0 Answers0