Skip to content

Consider mitigating the JCC erratum in the JIT (Nov. 2019) #13795

@damageboy

Description

@damageboy

What

In continuation of #13794, It might be worthwhile to consider applying the same fixes suggested by intel in their erratum:
https://www.intel.com/content/dam/support/us/en/documents/processors/mitigations-jump-conditional-code-erratum.pdf

To the code generated by the JIT.

It is hard for me, personally to evaluate the impact on the performance of generated code produced by the JIT, but my very small anecdotal experience shows anywhere from 1%-2% degradation for my own code, to potential 20% degradation in very specific instances.

This is in accordance with Intel's own guidance (Section 2.2):

Intel has observed performance effects associated with the workaround ranging from
0-4% on many industry-standard benchmarks. 1 In subcomponents of these
benchmarks, Intel has observed outliers higher than the 0-4% range.

Affected opcodes

The update affects all forms of jumps, direct and indirect when the instruction itself is either ending or crossing on a 32-byte boundary (Section 2.1):

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 Instructions include all jump types: conditional jump (Jcc), macro-
fused op-Jcc (where op is one of cmp, test, add, sub, and, inc, or dec), direct
unconditional jump, indirect jump, direct/indirect call, and return.

image

Proposed mitigation for code-generation

The proposed fix by intel is to stuff the affected opcodes:

  • jcc
  • fused
  • jmp
  • call
  • ret

with 0x2e prefix (End of section 2.4.0):

The advice to software developers is to align the jae instruction so that it does not
cross a 32-byte boundary. In the example, this is done by adding the benign prefix
0x2e four times before the first push %rbp instruction so that the cmp instruction,
which started at offset 1c, will instead start at offset 20. Hence the macro-fused cmp+jae instruction will not cross a 32-byte boundary.

Affected processors

Section 4.0 specifically lists no less than 40 Intel CPUs, covering the breadth of their product line, that are affected by this update:

Family Stepping Series
06_8EH 9 8th Generation Intel® CoreTM Processor Family based on microarchitecture code name Amber Lake Y
06_8EH C 8th Generation Intel® CoreTM Processor Family based on microarchitecture code name Amber Lake Y
06_55 7 2nd Generation Intel® Xeon® Scalable Processors based on microarchitecture code name Cascade Lake (server)
06_9EH A 8th Generation Intel® CoreTM Processor Family based on microarchitecture code name Coffee Lake H
06_9EH A 8th Generation Intel® CoreTM Processor Family based on microarchitecture code name Coffee Lake S
06_8EH A 8th Generation Intel® CoreTM Processor Family based on microarchitecture code name Coffee Lake U43e
06_9EH B 8th Generation Intel® CoreTM Processor Family based on microarchitecture code name Coffee Lake S (47)
06_9EH B Intel® Celeron® Processor G Series based on microarchitecture code name Coffee Lake S (48)
06_9EH A 8th Generation Intel® CoreTM Processor Family based on microarchitecture code name Coffee Lake S (69) x/KBP
06_9EH A Intel® Xeon® Processor E Family based on microarchitecture code name Coffee Lake S (610)
06_9EH A Intel® Xeon® Processor E Family based on microarchitecture code name Coffee Lake S (611)
06_9EH A Intel® Xeon® Processor E Family based on microarchitecture code name Coffee Lake S (612)
06_9EH A Intel® Xeon® Processor E Family based on microarchitecture code name Coffee Lake S (413)
06_9EH A Intel® Xeon® Processor E Family based on microarchitecture code name Coffee Lake S (414)
06_9EH A Intel® Xeon® Processor E Family based on microarchitecture code name Coffee Lake S (415)
06_9EH D 9th Generation Intel® CoreTM Processor Family based on microarchitecture code name Coffee Lake H (816)
06_9EH D 9th Generation Intel® CoreTM Processor Family based on microarchitecture code name Coffee Lake S (817)
06_8EH C 10th Generation Intel® CoreTM Processor Family based on microarchitecture code name Comet Lake U42
06_A6H 0 10th Generation Intel® CoreTM Processor Family based on microarchitecture code name Comet Lake U62
06_9EH 9 8th Generation Intel® CoreTM Processor Family based on microarchitecture code name Kaby Lake G
06_9EH 9 7th Generation Intel® CoreTM Processor Family based on microarchitecture code name Kaby Lake H
06_AEH A 8th Generation Intel® CoreTM Processor Family based on microarchitecture code name Kaby Lake Refresh U (422)
06_9EH 9 7th Generation Intel® CoreTM Processor Family based on microarchitecture code name Kaby Lake S
06_8EH 9 7th Generation Intel® CoreTM Processor Family based on microarchitecture code name Kaby Lake U
06_8EH 9 7th Generation Intel® CoreTM Processor Family based on microarchitecture code name Kaby Lake U23e
06_9EH 9 Intel® CoreTM X-series Processors based on microarchitecture code name Kaby Lake X
06_9EH 9 Intel® Xeon® Processor E3 v6 Family Kaby Lake Xeon E3
06_8EH 9 7th Generation Intel® CoreTM Processor Family based on microarchitecture code name Kaby Lake Y
06_55H 4 Intel® Xeon® Processor D Family based on microarchitecture code name Skylake D Bakerville
06_5E 3 6th Generation Intel® CoreTM Processor Family based on microarchitecture code name Skylake H
06_5E 3 6th Generation Intel® CoreTM Processor Family based on microarchitecture code name Skylake S
06_55H 4 Intel® Xeon® Scalable Processors based on microarchitecture code name Skylake Server
06_4E 3 6th Generation Intel® CoreTM Processors based on microarchitecture code name Skylake U
06_4E 3 6th Generation Intel® CoreTM Processor Family based on microarchitecture code name Skylake U23e
06_55H 4 Intel® Xeon® Processor W Family based on microarchitecture code name Skylake W
06_55H 4 Intel® CoreTM X-series Processors based on microarchitecture code name Skylake X
06_55H 4 Intel® Xeon® Processor E3 v5 Family based on microarchitecture code name Skylake Xeon E3
06_4E 3 6th Generation Intel® CoreTM Processors based on microarchitecture code name Skylake Y
06_8EH B 8th Generation Intel® CoreTM Processors based on microarchitecture code name Whiskey Lake U
06_8EH C 8th Generation Intel® CoreTM Processors based on microarchitecture code name Whiskey Lake U

Proposed fix to the JIT

I personally hold the position that this isn't a small issue (even if we take intel's claim of 0%-4% as-is) and that it is not going away: neither in terms of performance impact nor when considering the breadth of the product line affected by this issue.
I think that it would be the desired behavior, from the standpoint of the JIT, to detect if this microcode update is applied or if the CPU model is from the affected family and generate code that would not trigger the degradation.

On the face of it, while AMD processors are completely unaffected by this erratum, they also seem to not suffer adverse effects when running code that was generated by patched up assemblers:

https://www.phoronix.com/scan.php?page=news_item&px=AMD-With-Intel-JCC-Assembler

category:cq
theme:alignment
skill-level:intermediate
cost:medium

Metadata

Metadata

Assignees

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions