From 680e0147239593167875f17306f01144f2c72b72 Mon Sep 17 00:00:00 2001 From: Yousaf Kaukab Date: Fri, 11 Oct 2024 16:00:11 +0200 Subject: [PATCH] Add AMD EPYC-5 tuning guide for SLE15-SP6 Baremetal only Signed-off-by: Yousaf Kaukab --- DC-SBP-AMD-EPYC-5-SLES15SP6 | 17 + images/src/png/amd-epyc-5-graph-stream.png | Bin 0 -> 28724 bytes images/src/png/amd-epyc-5-nas.png | Bin 0 -> 27107 bytes images/src/png/amd-epyc-5-topology.png | Bin 0 -> 72580 bytes xml/MAIN-SBP-AMD-EPYC-5-SLES15SP6.xml | 3555 ++++++++++++++++++++ 5 files changed, 3572 insertions(+) create mode 100644 DC-SBP-AMD-EPYC-5-SLES15SP6 create mode 100644 images/src/png/amd-epyc-5-graph-stream.png create mode 100644 images/src/png/amd-epyc-5-nas.png create mode 100644 images/src/png/amd-epyc-5-topology.png create mode 100644 xml/MAIN-SBP-AMD-EPYC-5-SLES15SP6.xml diff --git a/DC-SBP-AMD-EPYC-5-SLES15SP6 b/DC-SBP-AMD-EPYC-5-SLES15SP6 new file mode 100644 index 00000000..25269fce --- /dev/null +++ b/DC-SBP-AMD-EPYC-5-SLES15SP6 @@ -0,0 +1,17 @@ +## Doc config file for the DAPS example document +## defined by MAIN-SBP-AMD-EPYC-5-SLES15SP6.xml +## +## See /etc/daps/config for documentation of the settings below + +## Mandatory Parameter +MAIN="MAIN-SBP-AMD-EPYC-5-SLES15SP6.xml" + +## Custom Stylesheets +## (if not defined, the DocBook stylesheets will be used) +## +STYLEROOT=/usr/share/xml/docbook/stylesheet/sbp +FALLBACK_STYLEROOT=/usr/share/xml/docbook/stylesheet/suse2022-ns + +DOCBOOK5_RNG_URI="http://docbook.org/xml/5.2/rng/docbookxi.rnc" + +XSLTPARAM="--stringparam publishing.series=sbp" diff --git a/images/src/png/amd-epyc-5-graph-stream.png b/images/src/png/amd-epyc-5-graph-stream.png new file mode 100644 index 0000000000000000000000000000000000000000..d44e94544085cc88c859422af313e6549c3aa8ce GIT binary patch literal 28724 zcmeIb2UyhkmMvQ5wp*mT&7xo^K}Dbi0m*h7utdQ`js|jS0YNghwsxzC5=62IQGz4^ zK?KxRGDsFlDoG?1f@G+AYnR>UoSAp-y>H%|xijy()89996srF5_uG5zwbtJLzF%FH z@9X7XGZ+j$*6tk#8H|}p491LAU(Lo(q~3;2$N$W9{E2n=EBxp2)$!l(_qjjs)^%hs z_>a*4O}nQOV~HQiIqlSOI%IF=1P{zCmYM7tDH?894+nbR!NFWic4== zW#Q!Xv%G}F-#;L3?_e&myL|m^24fY2wd2Rbr^0)h+^=X3MX=c}4NX3!(cjJ6vVP6R zwSB+V?Y9NXq<@!RZM5dzr6u!J9p_86nzRKTo&IvUuj+v_*F(Ol2)Oi1 z-MytVb~yg=_|%Vl^LDXj$V}&(npmqc!iqaJt@nvdWQ>(|W*w(5P5E)}tytr<+Bb{# z;lF9P6Q5t+JZPMOKQQv+4~H2#0F7#_wt@Ner*wXC{3 z`N_|FZ~o<#hYlP#(02mM*rGi&G&IF+=;P;}dZ`B6PJ@Wr-Ffd9jO43uHa~G2+BmWl zAF?@S`c8KhYlTDzI=Jg(H9q(EI&b|BE|38SMg4BQ^u}Q=YqE3V`s6E ztv1KfTf8Qig%=iyRwn4n1~0HX)A+|qoR5E~OeqnEDpH)=5bNSK(&%m5z~p`ZYNpK< zhfj|)Y*7vGT|AeVac1 zHpJTT!wu7~=uz1upF4NX#-j1cj|%hm*bc=Ao&6|V-FZ_*DG)#RTXBQas=`^z{j9+a z?2PhOmX?;Tx6hp#C^qIu;%$}ElPd|45@AUmFSs&q=?|-V-=r05c#l^-w5$@2iSlw2 z-WPiKOg652dzVR}@3`x-NK zQ;xIx9F4M88hSVnvOdOobg3B^wG{@aHE>3_oR+SdIPFN!;rgD; z&d8`g^3Q6OXMBtEzOw2~EmxMC?0;UB>&;!^-jkf!5o(>{&|XyfKUNyPCj>3sH^F*i&=T( zRPxB+Sh=^dTCjMj_f(yCwEIXO%YW84i#^`D=X{QqXkU^$y3@JoWZhxSu>~vA1J%C5 z(Ja#FUG0rjl>26hcu8fnnqzlDM#oT{ae1>l8%LD3d7adgGtnp4bthoJo6F{wZs%7D z{6-@C2bPSxS?%lOV}l)G_8p_Ge&w_Zv-_WY6QbZ^mopf_KHmD$SAVG9M1KwMvaL>j ztlp42R%$+FAI;?O%!SD`|A*FfeV#2dSe{|y5u1ia=dQFYD_oSAq+uGWuHpEj^&(zKltQz-P?5LRf!E$fTplkorIcnuXZXa$k3kBVK zt}^RS))`h+S6BBac}@(MCS){^CwI&a{Sr2gVt3wu5L>q0+wIx?R|H;;<=@yu*foK2!wF)86&UPw8bmX@|m!OjLDPOs-W9V;Qh zHo0{w4NKDe+1a^>*4io9k!BxW-OTJsDK3)y#zt-CCTz^~J-EO6Uk<7%eEMU79-SOzy3jB`oYsb7zZ>17)a&mTRXxm%1D=GAI9b6C~K=nMe_OjwhOi& zI%KFBl-&CAcZ8)p83ZupREoAYlQ$dhtBh`Z?(uc=UI*1<$M8cst4SDET9m7yzmw?5 zw>Xc7RpTE|7SZ!T9{LoSkGCGcL^urDVtLSQxF@7HqeXf9xp{>PG!!drgt}`JibKpJ zLsq&pZtiW!D6dcziqJOpOj{u|2gh3VyH8E*CY_{J#n;3{l{!kpf|+u|uW`IXclQ>y z2OCFrRmGS;{bd%CMKMJc?6*qgmwrM~^{M9Oweh<2+EUF*Locn6lN6A(+f;0hJ#4XW z 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 ba;KHWedV;v^TukTaacRmcRcvXoXh@y> literal 0 HcmV?d00001 diff --git a/images/src/png/amd-epyc-5-nas.png b/images/src/png/amd-epyc-5-nas.png new file mode 100644 index 0000000000000000000000000000000000000000..eb0c6c628cfdde37d5821d6434e8e6e3b5662ce8 GIT binary patch literal 27107 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 literal 0 HcmV?d00001 diff --git a/images/src/png/amd-epyc-5-topology.png b/images/src/png/amd-epyc-5-topology.png new file mode 100644 index 0000000000000000000000000000000000000000..bcd10d1a879d110690c730f1beb5c28224d0ed75 GIT binary patch literal 72580 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 G_x}$rRZi*v literal 0 HcmV?d00001 diff --git a/xml/MAIN-SBP-AMD-EPYC-5-SLES15SP6.xml b/xml/MAIN-SBP-AMD-EPYC-5-SLES15SP6.xml new file mode 100644 index 00000000..32b618ce --- /dev/null +++ b/xml/MAIN-SBP-AMD-EPYC-5-SLES15SP6.xml @@ -0,0 +1,3555 @@ + + + +%entity; +]> + +

+ + + Optimizing Linux for AMD EPYC™ 9005 Series Processors with SUSE Linux Enterprise 15 + SP6 + SUSE Linux Enterprise Server + 15 SP6 + + + https://github.com/SUSE/suse-best-practices/issues/new + Optimizing Linux for AMD EPYC™ 9005 Series Processors with SUSE Linux Enterprise + 15 SP6 + + https://github.com/SUSE/suse-best-practices/edit/main/xml/ + + + SUSE Best Practices + + + Tuning & Performance + + + Configuration + + Optimizing Linux for AMD EPYC™ 9005 Series Processors with SUSE Linux Enterprise + 15 SP6 + Overview of the AMD EPYC* 9005 Series Processors and tuning of + computational-intensive workloads on SUSE Linux Enterprise Server 15 SP6. + + SLES + AMD EPYC* + + + SUSE Linux Enterprise 15 SP6 + AMD EPYC™ 9005 Series Processors + 2024-11-15 + + + + + Mel + Gorman + + + Senior Kernel Engineer + SUSE + + + + + + Martin + Jambor + + + Tool Chain Developer + SUSE + + + + + Brent + Hollingsworth + + + Engineering Manager + AMD + + + + + + + + + + + + + + + 2024-11-15 + + + + The document at hand provides an overview of both the AMD EPYC™ 9005 Series + Classic and AMD EPYC™ 9005 Series Dense Processors. It details how some + computational-intensive workloads can be tuned on SUSE Linux Enterprise Server + 15 SP6. + + Disclaimer: + Documents published as part of + the SUSE Best Practices series have been contributed voluntarily by SUSE employees + and third parties. They are meant to serve as examples of how particular actions + can be performed. They have been compiled with utmost attention to detail. However, + this does not guarantee complete accuracy. SUSE cannot verify that actions described + in these documents do what is claimed or whether actions described have unintended + consequences. SUSE LLC, its affiliates, the authors, and the translators may not + be held liable for possible errors or the consequences thereof. + + + + + + + Overview + + The AMD EPYC 9005 Series Processor is the 5th generation of the AMD EPYC server + class processors family. It is based on the Zen 5 microarchitecture introduced in 2024. + AMD EPYC 9005 Series classic processors supports up to 128 Zen5 cores (256 threads) whereas + AMD EPYC 9005 Series Dense Processors support up to 192 Zen5c cores (384 threads). Both support 12 + memory channels per socket. At the time of writing, 1-socket and 2-socket models are expected + to be available from Original Equipment Manufacturers (OEMs) in 2024. This document provides + an overview of the AMD EPYC 9005 Series Classic Processor and how computational-intensive + workloads can be tuned on SUSE Linux Enterprise Server 15 SP6. Additional details about the + AMD EPYC 9005 Series Dense Processor are provided where appropriate. + + + + + AMD EPYC 9005 Series Classic Processor architecture + + Symmetric multiprocessing (SMP) systems are those that + contain two or more physical processing cores. Each core may have two threads if Symmetric + multithreading (SMT) is enabled, with some resources being shared between SMT siblings. To + minimize access latencies, multiple layers of caches are used with each level being larger but + with higher access costs. Cores may share different levels of cache which should be considered + when tuning for a workload. + + Historically, a single socket contained several cores sharing a hierarchy of caches and + memory channels and multiple sockets were connected via a memory interconnect. Modern + configurations may have multiple dies as a Multi-Chip Module + (MCM) with one set of interconnects within the socket and a separate interconnect + for each socket. This means that some CPUs and memory are faster to access + than others depending on the distance. This should be considered when tuning + for Non-Uniform Memory Architecture (NUMA) as all memory + accesses may not reference local memory incurring a variable access penalty. + + The 5th Generation AMD EPYC Processor has an MCM design with up to sevneteen dies + on each package. From a topology point of view, this is significantly different to the + 1st Generation AMD EPYC Processor design. However, it is similar to the 4th Generation AMD EPYC + Processor other than the increase in die count. One die is a central IO die through + which all off-chip communication passes through. The basic building block of a compute + die is an eight-core Core CompleX (CCX) with its own L1-L3 cache hierarchy. Similar to + the 4th Generation AMD EPYC Processor, one Core Complex Die (CCD) consists of one CCX + connected via an Infinity Link to the IO die, as opposed to two CCXs used in the 2nd + Generation AMD EPYC Processor. This allows direct communication within a CCD instead + of using the IO link maintaining reduced communication and memory access latency. + A 128-core 5th Generation AMD EPYC Processor socket therefore consists of 16 CCDs + consisting of 16 CCXs (containing 8 cores each) or 128 cores in total (256 threads + with SMP enabled) with one additional IO die for 17 dies in total. This is a large + increase in the core count relative to the 4th Generation AMD EPYC Processor. + + Both the 4th and 5th Generation AMD EPYC Processors potentially have a larger + L3 cache. In a standard configuration, a 5th Generation AMD EPYC Processor has + 32MB L3 cache. Some CPU chips may also include an AMD V-Cache expansion that can + triple the size of the L3 cache. This potentially provides a major performance boost + to applications as more active data can be stored in low-latency cache. The exact + performance impact is variable, but any memory-intensive workload should benefit from + having a lower average memory access latency because of a larger cache. + + Communication between the chip and memory happens via the IO die. Each CCD has one + dedicated Infinity Fabric link to the IO die. The practical consequence of this architecture + versus the 1st Generation AMD EPYC Processor is that the topology is simpler. + The first generation had separate memory channels per die and links between dies giving two + levels of NUMA distance within a single socket and a third distance when communicating between sockets. This meant + that a two-socket machine for EPYC had 4 NUMA nodes (3 levels of NUMA distance). The + 2nd Generation AMD EPYC Processor has only 2 NUMA nodes (2 levels of NUMA distance) + which makes it easier to tune and optimize. The NUMA distances are the same for the + 3rd, 4th and 5th Generation AMD EPYC Processors. + + The IO die has a total of 12 memory controllers supporting + DDR5 Dual Inline Memory Modules (DIMMs) with the + maximum supported speed expected to be DDR5-6000 at the time of writing. This implies + a peak channel bandwidth of 48 GB/sec or 576 GB/sec total throughput across a + socket. The exact bandwidth depends on the DIMMs selected, the number of memory channels + populated, how cache is used and the efficiency of the application. Where possible, + all memory channels should have a DIMM installed to maximize memory bandwidth. + + While the topologies and basic layout is similar between the 4th and 5th + Generation AMD EPYC Processors, there are several micro-architectural + differences. The Instructions Per Cycle (IPC) has + improved by 17% on average for enterprise and cloud workloads and 37% higher in AI and + high performance computing (HPC), although the exact improvement is workload-dependent. + The improvements are due to a variety of factors including, increased cache bandwidth, a larger L1d cache, + improvements in branch prediction, wider front-end, increased number of Arithmetic + Logic Units (ALUs), increased floating point throughput, support for AVX-512 with 512-bit data-path. + The degree to which these changes affect performance varies between applications. + + + Power management on the links is careful to minimize the amount of power + required. If the links are idle, the power may be used to boost the frequency of + individual cores. Hence, minimizing access is not only important from a memory + access latency point of view, but it also has an impact on the speed of individual + cores. + + There are 128 IO lanes supporting PCIe Gen 5.0 per socket. Lanes can be + used as Infinity links, PCI Express links, SATA links (maximum 32 links) or CXL 2.0 links + (maximum 64 links). The exact number of PCIe 5.0 and configuration links vary by chip and + motherboard. This allows very large IO configurations and a high degree of flexibility, + given that either IO bandwidth or the bandwidth between sockets can be optimized, + depending on the OEM requirements. The most likely configuration is that the number + of PCIe links will be the same for 1- and 2-socket machines, given that some lanes per + socket will be used for inter-socket communication. While some links must be used + for inter-socket communication, adding a socket does not compromise the number + of available IO channels. The exact configuration used depends on the platform. + + + + + AMD EPYC 9005 Series Classic Processor topology + + below shows the topology of an example two socket machine + with a fully populated memory configuration generated by the lstopo + tool. + +
+ AMD EPYC 9005 Series Classic Processor Topology + + + + + + + + +
+ + This tool is part of the hwloc-gui package. The two packages + correspond to each socket. The CCXs consisting of 8 cores (16 threads) each should + be clear, as each CCX has one L3 cache and each socket has 16 CCXs resulting in 128 + cores (256 threads). Not obvious are the links to the IO die, but the IO die should + be taken into account when splitting a workload to optimize bandwidth to memory. In + this example, the IO channels are not heavily used, but the focus will be on CPU and + memory-intensive loads. If optimizing for IO, it is recommended that, where possible, + the workload is located on the nodes local to the IO channel. + + The computer output below shows a conventional view of the topology using the + numactl tool which is slightly edited for clarity. The CPU IDs + that map to each node are reported on the node X cpus: lines. They note + the NUMA distances on the table at the bottom of the computer output. Node 0 and node + 1 are a distance of 32 apart as they are on separate sockets. The distance is not + a guarantee of the access latency, it is an estimate of the relative difference. The + general interpretation of this distance would suggest that a remote node is 3.2 times + longer than a local memory access but the actual latency cost can be different. + + epyc:~ # numactl --hardware +node 0 cpus: 0 .. 127 256 .. 383 +node 0 size: 385996 MB +node 0 free: 384139 MB +node 1 cpus: 128 .. 255 384 .. 511 +node 1 size: 386740 MB +node 1 free: 385440 MB +node distances: +node 0 1 + 0: 10 32 + 1: 32 10 + + + Note that the two sockets displayed are masking some details. There + are multiple CCDs and multiple channels meaning that there are slight differences + in access latency even to local memory. If an application is so sensitive to + latency that it needs to be aware of the precise relative distances, then the + Nodes Per Socket (NPS) value can be adjusted + in the BIOS. If adjusted, numactl will show additional nodes + and the relative distances between them. + + Finally, the cache topology can be discovered in a variety of fashions. In + addition to lstopo which can provide the information, the + level, size and ID of CPUs that share cache can be identified from the files under + /sys/devices/system/cpu/cpuN/cache. + + +
+ + + AMD EPYC 9005 Series Dense Processor + + The AMD EPYC 9005 Series Dense Processor launched in 2024. While the fundamental + microarchitecture is based on the Zen 5 compute core, there are some + important differences between it and the AMD EPYC 9005 Series Classic Processors. Both + processors are socket-compatible, have the same number of memory channels and the + same number of I/O lanes. This means that the processors may be used interchangeably + on the same platform with the same limitation that dual-socket configurations must + use identical processors. Both processors use the same Instruction Set + Architecture (ISA). This means that code optimized for one processor will run + without modification on the other. + + Despite the compatible ISA, the processors are physically different using a + manufacturing process focused on increased density for both the CPU core and the + physical cache. The L1 and L2 caches have the same capacity. The L3 cache capacity per core is half + the capacity of the AMD EPYC 9005 Series Classic Processor as twice as many cores are placed on + each CCDs. The basic CCX structure for both the AMD EPYC 9005 Series Dense and + 9005 Series Classic processor is similar but each CCD for the AMD EPYC 9005 Series + Dense has 16 cores instead of 8. While the AMD EPYC 9005 Series Classic can have up to 16 + CCDs (with 1 CCX each) within a socket, the AMD EPYC 9005 Series Dense processor can have up to + 12 CCDs, each with 16 cores. This increases the maximum number of its cores per socket from 128 + cores to 192. Finally, the Thermal Design Points (TDPs) differ + for the AMD EPYC 9005 Series Dense processor, with different frequency scaling limits + and generally a lower peak frequency. While each individual core may achieve less peak + performance than the AMD EPYC 9005 Series Classic Processor, the total peak compute + throughput available is higher due to the increased number of cores. + + The intended use case and workloads determine which processor is superior. The + key advantage of the AMD EPYC 9005 Series Dense Processor is packing more cores within + the same socket. This may benefit Cloud or HyperScale environments in that more + containers or virtual machines can use uncontested CPUs for their workloads within + the same physical machine. As a result, physical space in data centers can potentially + be reduced. It may also benefit some HPC workloads that are primarily CPU and memory bound. + For example, some HPC workloads scale to the number of available cores working on data sets that + are too large to fit into a typical cache. For such workloads, the AMD EPYC 9005 Series Dense + Processor may be ideal. + + + + + Memory and CPU binding + + NUMA is a scalable memory architecture for multiprocessor systems that can reduce + contention on a memory channel. A full discussion on tuning for NUMA is beyond the scope for + this document. But the document A NUMA API for Linux at provides a valuable introduction. + + The default policy for programs is the local policy. A program which calls + malloc() or mmap() reserves virtual address space but + does not immediately allocate physical memory. The physical memory is allocated the first time + the address is accessed by any thread and, if possible, the memory will be local to the + accessing CPU. If the mapping is of a file, the first access may have occurred at any time in + the past so there are no guarantees about locality. + + When memory is allocated to a node, it is less likely to move if a thread changes to a CPU + on another node or if multiple programs are remote-accessing the data unless Automatic NUMA Balancing (NUMAB) is enabled (see ). + When NUMAB is enabled, unbound process accesses are sampled. If there are enough remote accesses, then the data will + be migrated to local memory. This mechanism is not perfect and incurs overhead of its own. + This can be important for performance for thread and process migrations between nodes to be + minimized and for memory placement to be carefully considered and tuned. + + The taskset tool is used to set or get the CPU affinity for new or + existing processes. An example usage is to confine a new process to CPUs local to one node. + Where possible, local memory will be used. But if the total required memory is larger than the + node, then remote memory can still be used. In such configurations, it is recommended to size + the workload such that it fits in the node. This avoids that any of the data is being paged + out when kswapd wakes to reclaim memory from the local node. + + numactl controls both memory and CPU policies for processes that it + launches and can modify existing processes. In many respects, the parameters are easier to + specify than taskset. For example, it can bind a task to all CPUs on a + specified node instead of having to specify individual CPUs with taskset. + Most importantly, it can set the memory allocation policy without requiring application + awareness. + + Using policies, a preferred node can be specified where the task will use that node if + memory is available. This is typically used in combination with binding the task to CPUs on + that node. If a workload's memory requirements are larger than a single node and predictable + performance is required, then the interleave policy will round-robin + allocations from allowed nodes. This gives suboptimal but predictable access latencies to main + memory. More importantly, interleaving reduces the probability that the operating system (OS) + will need to reclaim any data belonging to a large task. + + Further improvements can be made to access latencies by binding a workload to + a single CCD within a node. As L3 caches are shared within a CCD on the 3rd, 4th + and 5th Generation AMD EPYC Processors, binding a workload to a CCD avoids L3 cache + misses caused by workload migration. This is an important difference from the + 2nd Generation AMD EPYC Processor which favored binding within a CCX. + + In most respects, the guidance for optimal bindings for cache and nodes remains + the same between the 3rd, 4th and 5th Generation AMD EPYC Processors. However, with SUSE + Linux Enterprise 15 SP6, the necessity to bind specifically to the L3 cache for + optimal performance is relaxed. The CPU scheduler in SUSE Linux Enterprise 15 SP6 has + superior knowledge of the cache topology of all generations of the AMD EPYC Processors + and how to balance load between CPU caches, NUMA nodes and memory channels. + + + CPU Scheduler Awareness of Cache Topology + + With SUSE Linux Enterprise 15 SP6 having superior knowledge of the CPU cache + topology and how to balance load, tuning specifically has a smaller impact to performance + for a given workload. This is not a limitation of the + operating system. It is a side-effect of the baseline performance being improved on + AMD EPYC Processors in general. + + + + See examples below on how taskset and numactl can + be used to start commands bound to different CPUs depending on the topology. + + # Run a command bound to CPU 1 +epyc:~ # taskset -c 1 [command] + +# Run a command bound to CPUs belonging to node 0 +epyc:~ # taskset -c `cat /sys/devices/system/node/node0/cpulist` [command] + +# Run a command bound to CPUs belonging to nodes 0 and 1 +epyc:~ # numactl –cpunodebind=0,1 [command] + +# Run a command bound to CPUs that share L3 cache with cpu 1 +epyc:~ # taskset -c `cat /sys/devices/system/cpu/cpu1/cache/index3/shared_cpu_list` [command] + + + + Tuning for local access without binding + + The ability to use local memory where possible and remote memory if necessary is + valuable. But there are cases where it is imperative that local memory always be used. If + this is the case, the first priority is to bind the task to that node. If that is not + possible, then the command sysctl vm.zone_reclaim_mode=1 can be used to + aggressively reclaim memory if local memory is not available. + + + Potential Hazard with <filename>vm.zone_reclaim_mode</filename> + + While this option is good from a locality perspective, it can incur high costs because + of stalls related to reclaim and the possibility that data from the task will be + reclaimed. Treat this option with a high degree of caution and testing. + + + + + Hazards with CPU binding + + There are three major hazards to consider with CPU binding. + + The first to watch for is remote memory nodes being used when the process is not + allowed to run on CPUs local to that node. The scenarios when this can occur + are outside the scope of this paper. However, a common reason is an IO-bound thread + communicating with a kernel IO thread on a remote node bound to the IO controller. + In such a setup, the data buffers managed by the application are stored in remote memory + incurring an access cost for the IO. + + While tasks may be bound to CPUs, the resources they are accessing, such as network or + storage devices, may not have interrupts routed locally. irqbalance + generally makes good decisions. But in cases where the network or IO is extremely + high-performance or the application has very low latency requirements, it may be necessary to + disable irqbalance using systemctl. When that is done, + the IRQs for the target device need to be routed manually to CPUs local to the target + workload for optimal performance. + + The second is that guides about CPU binding tend to focus on binding to a + single CPU. This is not always optimal when the task communicates with other threads, + as fixed bindings potentially miss an opportunity for the processes to use idle + CPUs sharing a common cache. This is particularly true when dispatching IO, be it + to disk or a network interface, where a task may benefit from being able to migrate + close to the related threads. It also applies to pipeline-based communicating threads + for a computational workload. Hence, focus initially on binding to CPUs sharing L3 + cache. Then consider whether to bind based on an L1/L2 cache or a single CPU using the + primary metric of the workload to establish whether the tuning is appropriate. + + The final hazard is similar: if many tasks are bound to a smaller set of CPUs, + then the subset of CPUs could be oversaturated even though there is spare CPU + capacity available. + + + + + CPUsets and memory control groups + + CPUsets are ideal when multiple workloads must be + isolated on a machine in a predictable fashion. CPUsets allow a machine to be partitioned + into subsets. These sets may overlap, and in that case they suffer from similar problems as + CPU affinities. In the event there is no overlap, they can be switched to + exclusive mode which treats them completely in isolation with relatively + little overhead. Similarly, they are well suited when a primary workload must be protected + from interference because of low-priority tasks. In such cases the low-priority tasks can be + placed in a CPUset. The caveat with CPUsets is that the overhead is higher than using + scheduler and memory policies. Ordinarily, the accounting code for CPUsets is completely + disabled. But when a single CPUset is created, there is a second layer of checks against + scheduler and memory policies. + + Similarly, memcg can be used to limit the amount of memory that can be + used by a set of processes. When the limits are exceeded, the memory will be reclaimed + by tasks within memcg directly without interfering with any other tasks. + This is ideal for ensuring there is no inference between two or more sets of tasks. Similar + to CPUsets, there is some management overhead incurred. This means, if tasks can simply be + isolated on a NUMA boundary, then this is preferred from a performance perspective. The major + hazard is that, if the limits are exceeded, then the processes directly stall to reclaim the + memory which can incur significant latencies. + + + + + <para>Without <package>memcg</package>, when memory gets low, the global reclaim daemon does + work in the background and if it reclaims quickly enough, no stalls are incurred. When + using <package>memcg</package>, observe the <package>allocstall</package> counter in + <filename>/proc/vmstat</filename> as this can detect early if stalling is a + problem.</para> + + </note> + + </sect2> + </sect1> + + <sect1 xml:id="sec-hp-storage-interrupt-affinity"> + <title>High performance storage devices and interrupt affinity + + High performance storage devices like Non-Volatile Memory Express + (NVMe) or Serial Attached SCSI (SAS) + controller are designed to take advantage of parallel IO submission. These devices typically + support a large number of submit and receive queues, which are tied to MSI-X interrupts. Ideally, these devices should provide as many MSI-X vectors as + there are CPUs in the system. To achieve the best performance, each MSI-X vector should be assigned + to an individual CPU. + + + + + Automatic NUMA balancing + + Automatic NUMA Balancing (NUMAB) is a feature that identifies and relocates + pages that are being accessed remotely for applications that are not NUMA-aware. There + are cases where it is impractical or impossible to specify policies. In such cases, the + balancing should be sufficient for throughput-sensitive workloads, but on occasion, + NUMAB may be considered hazardous as it incurs a cost. Under ideal conditions, + an application is NUMA aware and uses memory policies to control what memory is + accessed and NUMAB simply ignores such regions. However, even if an application does + not use memory policies, it is possible that the application still accesses mostly + local memory and NUMAB adds overhead confirming that accesses are local which is an + unnecessary cost. For latency-sensitive workloads, the sampling for NUMA balancing may + be too unpredictable and would prefer to incur the remote access cost or interleave + memory instead of using NUMA. The final corner case where NUMA balancing is a hazard + happens when the number of runnable tasks always exceeds the number of CPUs in a + single node. In this case, the load balancer (and potentially affine wakes) may + pull tasks away from the preferred node as identified by NUMAB resulting in + excessive sampling and migrations. + + If the workloads can be manually optimized with policies, then consider disabling NUMAB + by specifying numa_balancing=disable on the kernel + command line or via sysctl kernel.numa_balancing. The same applies if + it is known that the application is mostly accessing local memory. + + + Changes to Automatic NUMA Balancing + + While a disconnect between CPU Scheduler and NUMA Balancing placement decisions + still potentially exists in SUSE Linux Enterprise 15 SP6 when the machine is heavily + overloaded, the impact is much reduced relative to previous releases for most + scenarios. The placement decisions made by the CPU Scheduler and NUMA Balancing + are now coupled. Situations where the CPU scheduler and NUMA Balancing make + opposing decisions are relatively rare. + + + + + + + + Evaluating workloads + + The first and foremost step when evaluating how a workload should be tuned is + to establish a primary metric such as latency, throughput, operations per second + or elapsed time. When each tuning step is considered or applied, it is critical + that the primary metric be examined before conducting any further analysis. This is to avoid + intensive focus on a relatively wrong bottleneck. Make sure that the metric is measured + multiple times to ensure that the result is reproducible and reliable within reasonable + boundaries. When that is established, analyze how the workload is using different system + resources to determine what area should be the focus. The focus in this paper is on how + CPU and memory is used. But other evaluations may need to consider the IO subsystem, + network subsystem, system call interfaces, external libraries, etc. The methodologies + that can be employed to conduct this are outside the scope of this paper. But the book + Systems Performance: Enterprise and the Cloud by Brendan Gregg (see ) + is a recommended primer on the subject. + + + CPU utilization and saturation + + Decisions on whether to bind a workload to a subset of CPUs require that the CPU + utilization and any saturation risk is known. Both the ps and + pidstat commands can be used to sample the number of threads in a + system. Typically, pidstat yields more useful information with the + important exception of the run state. A system may have many threads, but if they are idle, + they are not contributing to utilization. The mpstat command can + report the utilization of each CPU in the system. + + High utilization of a small subset of CPUs may be indicative of a single-threaded + workload that is pushing the CPU to the limits and may indicate a bottleneck. Conversely, + low utilization may indicate a task that is not CPU-bound, is idling frequently or is + migrating excessively. While each workload is different, load utilization of CPUs may show a + workload that can run on a subset of CPUs to reduce latencies because of either migrations + or remote accesses. When utilization is high, it is important to determine if the system + could be saturated. The vmstat tool reports the number of runnable tasks + waiting for a CPU in the r column where any value over 1 indicates that wakeup + latencies may be incurred. While the exact wakeup latency can be calculated using trace + points, knowing that there are tasks queued is an important step. If a system is saturated, + it may be possible to tune the workload to use fewer threads. + + Overall, the initial intent should be to use CPUs from as few NUMA nodes as + possible to reduce access latency. However, there are exceptions. The AMD EPYC 9005 + Series Processor has a large number of high-speed memory channels to main memory, so + consider the workload thread activity. If they are cooperating threads or sharing + data, isolate them on as few nodes as possible to minimize cross-node memory + accesses. If the threads are completely independent with no shared data, it may + be best to isolate them on a subset of CPUs from each node. This is to maximize + the number of available memory channels and throughput to main memory. For some + computational workloads, it may be possible to use hybrid models such as MPI for + parallelization across nodes and OpenMP for threads within nodes. + + + Updating tuning for AMD EPYC 9005 Series Processor + + It is expected that tuning based on the AMD EPYC 7003 Series Processor + will also usually perform optimally on latter series processors including AMD EPYC 9005 + series. The main consideration is to account for potential differences in L3 cache sizes + because of AMD V-Cache if workloads are tuned specifically for cache size. Also, keep in + mind that CPU bindings based on caches may potentially be relaxed on SUSE Linux Enterprise + 15 SP6. + + + + + Transparent Huge Pages + + Huge pages are a feature that can improve performance in many cases. This is + achieved by reducing the number of page faults, the cost of translating virtual + addresses to physical addresses because of fewer layers in the page table and + being able to cache translations for a larger portion of memory. Transparent Huge Pages (THP) is supported for private + anonymous memory that automatically backs mappings with huge pages where anonymous + memory could be allocated as heap, malloc(), + mmap(MAP_ANONYMOUS), etc. There is also support for using THP + pages backed by tmpfs which can be configured at mount time + using the huge= mount option. While the THP feature has + existed for a long time, it has evolved significantly. + + Many tuning guides recommend disabling THP because of problems with early + implementations. Specifically, when the machine was running for long enough, the + use of THP could incur severe latencies and could aggressively reclaim memory in + certain circumstances. These problems were resolved by the time SUSE Linux + Enterprise Server 15 SP2 was released, and this is still the case for SUSE Linux + Enterprise Server 15 SP6. This means there are no good grounds for automatically + disabling THP because of severe latency issues without measuring the impact. However, + there are exceptions that are worth considering for specific workloads. + + Some high-end in-memory databases and other applications aggressively use + mprotect() to ensure that unprivileged data is never leaked. If + these protections are at the base page granularity, then there may be many THP splits + and rebuilds that incur overhead. It can be identified if this is a potential + problem by using strace or perf trace to + detect the frequency and granularity of the system call. If they are high-frequency, + consider disabling THP. It can also be sometimes inferred from observing the + thp_split and thp_collapse_alloc counters + in /proc/vmstat. + + Workloads that sparsely address large mappings may have a higher memory + footprint when using THP. This could result in premature reclaim or fallback to + remote nodes. An example would be HPC workloads operating on large sparse matrices. If + memory usage is much higher than expected, compare memory usage with and without + THP to decide if the trade-off is not worthwhile. This may be critical on AMD EPYC + 7003, 9004 and 9005 Series Processor given that any spillover will congest the Infinity + links and potentially cause cores to run at a lower frequency. + + + Sparsely addressed memory + This is specific to sparsely addressed memory. A secondary hint for this case may be + that the application primarily uses large mappings with a much higher + Virtual Size (VSZ, see ) than Resident Set Size (RSS). + Applications which densely address memory benefit from the use of THP by achieving greater + bandwidth to memory. + + + Parallelized workloads that operate on shared buffers with thread counts + exceeding the number of available CPUs on a single node may experience a slowdown + with THP if the granularity of partitioning is not aligned to the huge page. The + problem is that if a large shared buffer is partitioned on a 4K boundary, then false + sharing may occur whereby one thread accesses a huge page locally and other threads + access it remotely. If this situation is encountered, the granularity of sharing should + be increased to the THP size. But if that is not possible, disabling THP is an option. + + Applications that are extremely latency-sensitive or must always perform in a + deterministic fashion can be hindered by THP. While there are fewer faults, the time for + each fault is higher as memory must be allocated and cleared before being visible. The + increase in fault times may be in the microsecond granularity. Ensure this is a relevant + problem as it typically only applies to extremely latency-sensitive applications. The + secondary problem is that a kernel daemon periodically scans a process looking for + contiguous regions that can be backed by huge pages. When creating a huge page, there is a + window during which that memory cannot be accessed by the application and new mappings + cannot be created until the operation is complete. This can be identified as a problem with + thread-intensive applications that frequently allocate memory. In this case, consider + effectively disabling khugepaged by setting a large value in + /sys/kernel/mm/transparent_hugepage/khugepaged/alloc_sleep_millisecs. + This will still allow THP to be used opportunistically while avoiding stalls when calling + malloc() or mmap(). + + THP can be disabled. To do so, specify + transparent_hugepage=disable on the kernel command line, + at runtime via /sys/kernel/mm/transparent_hugepage/enabled + or on a per-process basis by using a wrapper to execute the workload that calls + prctl(PR_SET_THP_DISABLE). + + + + + User/kernel footprint + + Assuming an application is mostly CPU- or memory-bound, it is useful to determine if the + footprint is primarily in user space or kernel space. This gives a hint where tuning should + be focused. The percentage of CPU time can be measured on a coarse-grained fashion using + vmstat or a fine-grained fashion using mpstat. If an + application is mostly spending time in user space, then the focus should be on tuning the + application itself. If the application is spending time in the kernel, then it should be + determined which subsystem dominates. The strace or perf + trace commands can measure the type, frequency and duration of system calls as + they are the primary reasons an application spends time within the kernel. In some cases, an + application may be tuned or modified to reduce the frequency and duration of system calls. + In other cases, a profile is required to identify which portions of the kernel are most + relevant as a target for tuning. + + + + Memory utilization and saturation + + The traditional means of measuring memory utilization of a workload is to + examine the Virtual Size (VSZ) and + Resident Set Size (RSS). This can be done by + using either the ps or pidstat tool. + This is a reasonable first step but is potentially misleading when shared memory + is used and multiple processes are examined. VSZ is simply a measure of memory space reservation and + is not necessarily used. RSS may be double accounted if it is a shared segment + between multiple processes. The file /proc/pid/maps can be + used to identify all segments used and whether they are private or shared. The file + /proc/pid/smaps and /proc/pid/smaps_rollup + reveals more detailed information including the Proportional + Set Size (PSS). PSS is an estimate of RSS except it is divided + between the number of processes mapping that segment, which can give a more + accurate estimate of utilization. Note that the smaps and + smaps_rollup files are very expensive to read and should not be + monitored at a high frequency. This is especially the case if workloads are using large amounts of + address space, many threads or both. Finally, the Working Set + Size (WSS) is the amount of active memory required to complete computations + during an arbitrary phase of a program's execution. It is not a value that can be + trivially measured. But conceptually it is useful as the interaction between WSS + relative to available memory affects memory residency and page fault rates. + + On NUMA systems, the first saturation point is a node overflow when the + local policy is in effect. Given no binding of memory, when a node is + filled, a remote node’s memory will be used transparently and background reclaim + will take place on the local node. Two consequences of this are that remote access + penalties will be used and old memory from the local node will be reclaimed. If the + WSS of the application exceeds the size of a local node, then paging and re-faults + may be incurred. + + The first item to identify is whether a remote node overflow occurred, which is + accounted for in /proc/vmstat as the numa_hit, + numa_miss, numa_foreign, + numa_interleave, numa_local and + numa_other counters: + + + + numa_hit is incremented when an allocation uses the preferred + node where preferred may be either a local node or one specified by a memory + policy. + + + numa_miss is incremented when an alternative node is used to + satisfy an allocation. + + + numa_foreign is rarely useful but is accounted against a node + that was preferred. It is a subtle distinction from numa_miss that is rarely + useful. + + + numa_interleave is incremented when an interleave policy was used + to select allowed nodes in a round-robin fashion. + + + numa_local increments when a local node is used for an allocation + regardless of policy. + + + numa_other is used when a remote node is used for an allocation + regardless of policy. + + + + For the local memory policy, the numa_hit and + numa_miss counters are the most important to pay attention + to. An application that is allocating memory that starts incrementing the + numa_miss implies that the first level of saturation has + been reached. If monitoring the proc is undesirable, then the + numastat provides the same information. If this is observed on the + AMD EPYC 9005 Series Processor, it may be valuable to bind the application to nodes + that represent dies on a single socket. If the ratio of hits to misses is close to 1, + consider an evaluation of the interleave policy to avoid unnecessary reclaim. + + + NUMA statistics + + These NUMA statistics only apply at the time a physical page is allocated and are not + related to the reference behavior of the workload. For example, if a task running on node + 0 allocates memory local to node 0, then it will be accounted for as a + node_hit in the statistics. However, if the memory is shared with a + task running on node 1, all the accesses may be remote, which is a miss from the + perspective of the hardware but not accounted for in /proc/vmstat. + Detecting remote and local accesses at the hardware level requires using the hardware's + Performance Monitoring Unit to detect. See perf-mem(1) for further details. + + + When the first saturation point is reached, reclaim will be active. This + can be observed by monitoring the pgscan_kswapd and + pgsteal_kswapd counters in /proc/vmstat. If + this is matched with an increase in major faults or minor faults, then it may + be indicative of severe thrashing. In this case, the interleave policy should be + considered. An ideal tuning option is to identify if shared memory is the source + of the usage. If this is the case, then interleave the shared memory segments. This + can be done in some circumstances using numactl or by modifying + the application directly. + + More severe saturation is observed if the pgscan_direct + and pgsteal_direct counters are also increasing. These counters indicate + that the application is stalling while memory is being reclaimed. If the application + was bound to individual nodes, increasing the number of available nodes will + alleviate the pressure. If the application is unbound, it indicates that the WSS + of the workload exceeds all available memory. It can only be alleviated by tuning + the application to use less memory or increasing the amount of RAM available. + + A more generalized view of resource pressure for CPU, memory and IO can be + measured using the kernel Pressure + Stall Information feature enabled with the command + line psi=1. When enabled, proc files under + /proc/pressure show if some or all active tasks were stalled + recently contending on a resource. This information is not always available in + production. But if the information is available, the memory pressure information may be used to guide + whether a deeper analysis is necessary and which resource is the bottleneck. + + As before, whether to use memory nodes from one socket or two sockets depends + on the application. If the individual processes are independent, either socket + can be used. Where possible, keep communicating processes on the same socket + to maximize memory throughput while minimizing the socket interconnect traffic. + + + + + Other resources + + The analysis of other resources is outside the scope of this paper. However, + a common scenario is that an application is IO-bound. A superficial check can be made + using the vmstat tool. This tool checks what percentage of CPU time + is spent idle combined with the number of processes that are blocked and the values in + the bi and bo + columns. Similarly, if PSI is enabled, then the IO pressure file will show whether + some or all active tasks are losing time because of lack of resources. Further analysis + is required to determine if an application is IO rather than CPU- or memory-bound. + However, this is a sufficient check to start with. + + + + + + Power management + + Modern CPUs balance power consumption and performance through Performance States (P-States). Low utilization workloads may + use lower P-States to conserve power while still achieving acceptable performance. When + a CPU is idle, lower power idle states (C-States) can + be selected to further conserve power. However, this comes with higher exit latencies + when lower power states are selected. It is further complicated by the fact that, + if individual cores are idle and running at low power, the additional power can be + used to boost the performance of active cores. This means this scenario is not a + straightforward balance between power consumption and performance. More complexity + is added on the AMD EPYC 7003, 9004 and 9005 Series Processors whereby spare power may be + used to boost either cores or the Infinity links. + + The 5th Generation AMD EPYC Processor is capable of + making adjustments to voltage and frequency depending on the historical state of the + CPU. There is a latency penalty when switching P-States, but the AMD EPYC 9005 + Series Processor is capable of making fine-grained adjustments to reduce the likelihood + that the latency is a bottleneck. On SUSE Linux Enterprise + Server, the AMD EPYC 9005 Series Processor uses the acpi_cpufreq + driver by default. This allows P-states to be configured to match requested performance. However, + this is limited in terms of the full capabilities of the hardware. It cannot boost + the frequency beyond the maximum stated frequencies, and if a target is specified, + then the highest frequency below the target will be used. A special case is if the + governor is set to performance. In this situation + the hardware will use the highest available frequency in an attempt to work quickly + and then return to idle. + + What should be determined is whether power management is likely to be a factor for a + workload. A single thread workload that is CPU-bound is likely to run at the highest + frequency on a single core. Lastly, a workload that does not communicate heavily + with other processes and is mostly CPU-bound is unlikely to experience any side + effects because of power management. The exceptions are when load balancing moves + tasks away from active CPUs if there is a compute imbalance between NUMA nodes or + the machine is heavily overloaded. + + The workloads that are most likely to be affected by power management are those + that: + + + synchronously communicate between multiple threads. + + idle frequently. + + have low CPU utilization overall. + + + + It will be further compounded if the threads are sensitive to wakeup latency. + + Power management is critical, not only for power savings, but because power saved + from idling inactive cores can be used to boost the performance of active cores. On + the other side, low utilization tasks may take longer to complete if the task is not + active long enough for the CPU to run at a high frequency. In some cases, problems + can be avoided by configuring a workload to use the minimum number of CPUs necessary + for its active tasks. Deciding that means monitoring the power state of CPUs. + + The P-State and C-State of each CPU can be examined using the + turbostat utility. The computer output below shows an example, + slightly edited to fit the page, where a workload is busy on CPU 0 and other + workloads are idle. A useful exercise is to start a workload and monitor the output + of turbostat paying close attention to CPUs that have moderate + utilization and running at a lower frequency. If the workload is latency-sensitive, + it is grounds for either minimizing the number of CPUs available to the workload or + configuring power management. + + +Pac. Die Core CPU Avg_M Busy% Bzy_M TSC_M IRQ POLL C1 C2 POLL% C1% C2% +- - - - 1516 44.16 3432 1198 1.65 340109 90 706 6937 0.00 0.00 +0 0 0 0 463 13.24 3498 1200 0.26 2936 0 0 1406 0.00 0.00 +0 0 0 192 1 0.04 3499 1200 0.10 27 0 0 21 0.00 0.00 +0 0 1 1 3189 91.16 3498 1200 1.52 1792 0 0 18 0.00 0.00 +0 0 1 193 317 9.07 3498 1200 0.55 203 0 0 18 0.00 0.00 +0 0 2 2 3436 98.22 3498 1200 1.40 1905 0 0 3 0.00 0.00 +0 0 2 194 78 2.22 3500 1200 0.92 84 0 0 29 0.00 0.00 + + + If tuning CPU frequency management is appropriate, the following actions can be + taken to set the management policy to performance using the cpupower + utility: + + epyc:~# cpupower frequency-set -g performance +Setting cpu: 0 +Setting cpu: 1 +Setting cpu: 2 +... + + Persisting it across reboots can be done via a local init + script, via udev or via one-shot systemd + service file if necessary. Note that turbostat + will still show that idling CPUs use a low frequency. The impact of the policy is + that the highest P-State will be used as soon as possible when the CPU is active. In + some cases, a latency bottleneck will occur because of a CPU exiting idle. If this is + identified on the AMD EPYC 9005 Series Processor, restrict the C-state by specifying + processor.max_cstate=2 if lower P-States exist on the kernel command + line. This will prevent CPUs from entering lower C-states. The availability of + P-states can be determined with cpupower idle-info. It is expected + on the AMD EPYC 9005 Series Processor that the exit latency from C1 is very low. But + by allowing C2, it reduces interference from the idle loop injecting micro-operations + into the pipeline and should be the best state overall. It is also possible to set + the max idle state on individual cores using cpupower idle-set. If + SMT is enabled, the idle state should be set on both siblings. + + + + + Security mitigation + + On occasion, a security fix is applied to a distribution that has a performance + impact. The most notable example is Meltdown + and multiple variants of Spectre but includes + others such as ForeShadow (L1TF). The AMD EPYC 9005 Series Processor is immune to the + Meltdown variant and page table isolation is never active. However, it is vulnerable + to a subset of Spectre variants although retbleed + is a notable exception. The following table lists all security vulnerabilities that + affect the 5th Generation AMD EPYC Processor. In addition, it specifies which mitigations + are enabled by default for SUSE Linux Enterprise Server 15 SP6. + + + Security mitigations for AMD EPYC 9005 Series Processors + + + + + + + Vulnerability + Affected + Mitigations + + + + + + ITLB Multihit + + + No + + + N/A + + + + + L1TF + + + No + + + N/A + + + + + MDS + + + No + + + N/A + + + + + Meltdown + + + No + + + N/A + + + + + MMIO Stale Data + + + No + + + N/A + + + + + Retbleed + + + No + + + N/A + + + + + Speculative Store Bypass + + + Yes + + + prctl and seccomp policy + + + + + Spectre v1 + + + Yes + + + usercopy/swapgs barriers and __user pointer sanitization + + + + + Spectre v2 + + + Yes + + + Retpoline, RSB filling, and conditional IBPB, IBRS_FW, and STIBP + + + + + SRBDS + + + No + + + N/A + + + + + TSX Async Abort + + + No + + + N/A + + + + + Register File Data Sampling (RFDS) + + + No + + + N/A + + + + + Gather Data Sampling (GDS) + + + No + + + N/A + + + + + Speculative Return Stack Overflow (SRSO) + + + No + + + N/A + + + + +
+ + If it can be guaranteed that the server is in a trusted environment running + only known code that is not malicious, the mitigations=off + parameter can be specified on the kernel command line. This option disables all + security mitigations and may improve performance in some cases. However, at the + time of writing and in most cases, the gain on an AMD EPYC 9005 Series Processor is + marginal when compared to other CPUs. Evaluate carefully whether the gain is worth + the risk and if unsure, leave the mitigations enabled. + +
+ + + Hardware-based profiling + + The AMD EPYC 9005 Series Processor has extensive Performance Monitoring + Unit (PMU) capabilities. Advanced monitoring of a workload can be conducted via the + perf. The command supports a range of hardware events including + cycles, L1 cache access/misses, TLB access/misses, retired branch instructions and + mispredicted branches. To identify what subsystem may be worth tuning in the OS, + the most useful invocation is perf record -a -e cycles sleep 30. This + captures 30 seconds of data for the entire system. You can also call perf + record -e cycles command to gather a profile of a given workload. Specific + information on the OS can be gathered through tracepoints or creating probe points + with perf or trace-cmd. But the details on + how to conduct such analyses are beyond the scope of this paper. + + + + + Compiler selection + + SUSE Linux Enterprise ships with multiple versions of GCC. SUSE Linux Enterprise + 15 SP6 service packs ship with GCC 7 which at the time of writing is + GCC 7.5.0 with the package version 7-3.9.1. The + intention is to avoid unintended consequences when porting code that may affect + the building and operation of applications. The GCC 7 development + originally started in 2016, with a branch created in 2017 and GCC 7.5 + released in 2019. This means that the system compiler has no awareness of the AMD + EPYC 7002 or later Series processors. + + Fortunately, the add-on Developer Tools Module includes + additional compilers with the latest version currently based on GCC + 13.2.1. This compiler is capable of generating optimized code targeted at + the 4th Generation AMD EPYC Processor using the znver4 target. + It also provides additional support for OpenMP 5.0, extends the support + of OpenMP 5.1 features and very limited first support of OpenMP 5.2 + features. Unlike the system compiler, the major version of GCC shipped with the Developer Tools Module can change + during the lifetime of the product. It is expected that GCC 14 will + be included in future releases for generating optimized code for the 5th Generation + AMD EPYC Processor. Unfortunately, at the time of writing, there is not a version of + GCC available optimized for the AMD EPYC 9005 Series Processor specifically. + + The OS packages are built against a generic target. However, where applications and + benchmarks can be rebuilt from source, the minimum option should be + -march=znver4 for GCC 13 and later versions + of GCC. + + Further information on how to install the Developer Tools Module + and how to build optimized versions of applications can be found in the guide + Advanced optimization and new capabilities of GCC 12. + + + + + Candidate workloads + + The workloads that will benefit most from the 5th Generation AMD EPYC Processor + architecture are those that can be parallelized and are either memory or IO-bound. This + is particularly true for workloads that are NUMA friendly. They can + be parallelized, and each thread can operate independently for most of the + workload's lifetime. For memory-bound workloads, the primary benefit will be taking + advantage of the high bandwidth available on each channel. For IO-bound workloads, + the primary benefit will be realized when there are multiple storage devices, each + of which is connected to the node local to a task issuing IO. + + + Test setup + + The following sections will demonstrate how an OpenMP and MPI workload can + be configured and tuned on an AMD EPYC 9005 Series Processor reference platform. The + system has two processors, each with 128 cores and SMT enabled for a total of 256 + cores (512 logical CPUs). The peak bandwidth available to the machine depends on + the type of DIMMs installed and how the DIMM slots are populated. Note that the + peak theoretical transfer speed is rarely reached in practice, given that it can + be affected by the mix of reads/writes and the location and temporal proximity of + memory locations accessed. + + + + + Test setup + + + + + + + CPU + + + 2x AMD EPYC 9755 + + + + + Platform + + + AMD Engineering Sample Platform + + + + + Drive + + + Samsung SSD PM9A1 512GB + + + + + OS + + + SUSE Linux Enterprise Server 15 SP6 + + + + + Memory Type + + + 24x 32GB DDR5 + + + + + Memory Interleaving + + + Channel + + + + + Memory Speed + + + 4800 MT/sec + + + + + Kernel command line + + + + mitigations=off + + + + + +
+ +
+ + + Test workload: STREAM + + STREAM is a memory bandwidth benchmark + created by Dr. John D. McCalpin from the University of Virginia (for more + information, see https://www.cs.virginia.edu/stream/). It can be used to measure bandwidth + of each cache level and bandwidth to main memory while calculating four basic + vector operations. Each operation can exhibit different throughputs to main memory + depending on the locations and type of access. + + The benchmark was configured to run both single-threaded and parallelized with + OpenMP to take advantage of multiple memory controllers. The array of elements for + the benchmark was set at 536,870,912 elements at compile time so that each array + was 4096MB in size for a total memory footprint of approximately 12288 MB. The size + was selected in line with the recommendation from STREAM that the array sizes be + at least 4 times the total size of L3 cache available in the system. Pay special + attention to the exact size of the L3 cache if V-Cache is present. An array-size + offset was used so that the separate arrays for each parallelized thread would + not share a Transparent Huge Page. The reason is that NUMA balancing may + choose to migrate shared pages leading to some distortion of the results. + + + Test workload: STREAM + + + + + + + Compiler + + + gcc-13 (SUSE Linux) 13.2.1 + + + + + Compiler flags + + + + -Ofast -march=znver4 -mcmodel=medium -DOFFSET=512 + + + + + + OpenMP compiler flag + + + + -fopenmp + + + + + + OpenMP environment variables + + + + OMP_PROC_BIND=SPREAD + + + OMP_NUM_THREADS=32 + + + + + +
+ + The march=znver4 is a reflection of the compiler + available in SUSE Linux Enterprise 15 SP6 at the time of writing. + It should be checked if a later GCC version is + available in the Developer Tools Module that supported + march=znver5. The number of openMP threads was selected + to have at least one thread running for every memory channel by having one thread + per L3 cache available. The OMP_PROC_BIND parameter spreads + the threads such that one thread is bound to each available dedicated L3 cache to + maximize available bandwidth. This can be verified using perf, + as illustrated below with slight editing for formatting and clarity. + + epyc:~ # perf record -e sched:sched_migrate_task ./stream +epyc:~ # perf script +... + stream-nnn x: sched:sched_migrate_task: comm=stream pid=494780 prio=120 orig_cpu=0 dest_cpu=8 + stream-nnn x: sched:sched_migrate_task: comm=stream pid=494781 prio=120 orig_cpu=0 dest_cpu=16 + stream-nnn x: sched:sched_migrate_task: comm=stream pid=494782 prio=120 orig_cpu=0 dest_cpu=24 + stream-nnn x: sched:sched_migrate_task: comm=stream pid=494783 prio=120 orig_cpu=0 dest_cpu=32 + stream-nnn x: sched:sched_migrate_task: comm=stream pid=494784 prio=120 orig_cpu=0 dest_cpu=40 + stream-nnn x: sched:sched_migrate_task: comm=stream pid=494785 prio=120 orig_cpu=0 dest_cpu=48 + stream-nnn x: sched:sched_migrate_task: comm=stream pid=494786 prio=120 orig_cpu=0 dest_cpu=56 +... + + + Several options were considered for the test system that were unnecessary + for STREAM running on the AMD EPYC 9005 Series Processor but may be useful in other + situations. STREAM performance can be limited if a load/store instruction stalls to + fetch data. CPUs may automatically prefetch data based on historical behavior but it + is not guaranteed. In limited cases, depending on the CPU and workload, this may be + addressed by specifying -fprefetch-loop-arrays and depending + on whether the workload is store-intensive, -mprefetchwt1. + However, care must be taken as an explicitly scheduled prefetch may + disable a CPU's predictive algorithms and degrade performance. Similarly, for + some workloads branch mispredictions can be a major problem, and in some cases + breach mispredictions can be offset against I-Cache pressure by specifying + -funroll-loops. In the case of STREAM on the test + system, the CPU accurately predicted the branches rendering the unrolling of + loops unnecessary. For math-intensive workloads it can be beneficial to link the + application with -lmvec depending on the application. In the + case of STREAM, the workload did not use significant math-based operations and so + this option was not used. Some styles of code blocks and loops can also be optimized + to use vectored operations by specifying -ftree-vectorize and + explicitly adding support for CPU features such as -mavx2. In + all cases, STREAM does not benefit as its operations are very basic. But it should + be considered on an application-by-application basis and when building support + libraries such as numerical libraries. In all cases, experimentation is recommended + but caution advised. This holds particularly true when considering options like prefetch that may + have been advisable on much older CPUs or completely different workloads. Such + options are not universally beneficial or always suitable for modern CPUs such as + the AMD EPYC 9005 Series Processors. + + In the case of STREAM running on the AMD EPYC 9005 Series Processor, + it was sufficient to enable -Ofast. This includes the + -O3 optimizations to enable vectorization. In addition, + it gives some leeway for optimizations that increase the code size with additional + options for fast math that may not be standards-compliant. + + For OpenMP, the SPREAD option was used to spread the + load across L3 caches. OpenMP has a variety of different placement options + if manually tuning placement. But careful attention should be paid to + OMP_PLACES, given the importance of the L3 Cache topology in + AMD EPYC 9005 Series Processors, if the operating system does not automatically + place tasks appropriately. At the time of writing, it is not possible to + specify l3cache as a place similar to what MPI has. In + this case, the topology will need to be examined either with library support + such as hwloc, directly via the sysfs + or manually. While it is possible to guess via the CPUID, it is not recommended + as CPUs may be offlined or the enumeration may vary between platforms because of BIOS + implementations. An example specification of places based on L3 cache for the test + system is: + + +{0:8,256:8}, {8:8,264:8}, {16:8,272:8}, {24:8,280:8}, {32:8,288:8}, {40:8,296:8}, +{48:8,304:8}, {56:8,312:8}, {64:8,320:8}, {72:8,328:8}, {80:8,336:8}, {88:8,344:8}, +{96:8,352:8}, {104:8,360:8}, {112:8,368:8}, {120:8,376:8}, {128:8,384:8}, {136:8,392:8}, +{144:8,400:8}, {152:8,408:8}, {160:8,416:8}, {168:8,424:8}, {176:8,432:8}, {184:8,440:8}, +{192:8,448:8}, {200:8,456:8}, {204:8,464:8}, {216:8,472:8}, {224:8,480:8}, {232:8,488:8}, +{240:8,496:8}, {248:8,504:8} + + + shows the reported bandwidth for the + single, parallelized and parallelized with proper placement cases. The single-threaded + bandwidth for the basic Copy vector operation on a single core was 51.3 GB/sec. This is + higher than the theoretical maximum of a single DIMM, but the IO die interleave accesses, and + caching effects and prefetch still apply. The total throughput for each parallel operation + with SPREAD enabled ranged from 600 GB/sec to 700 GB/sec depending on + the type of operation and how efficiently memory bandwidth was used. This is twice as much + compared to default placement by OpneMP. This is very roughly scaling with the number of + memory channels available on the machine. + + + STREAM scores + + Higher STREAM scores can be reported by reducing the array sizes so that cache is + partially used with the maximum score requiring that each threads memory footprint fits + inside the L1 cache. Additionally, it is possible to achieve results closer to the + theoretical maximum by manual optimization of the STREAM benchmark using vectored + instructions and explicit scheduling of loads and stores. The purpose of this + configuration was to illustrate the impact of properly binding a workload that can be + fully parallelized with data-independent threads. + + + +
+ STREAM Bandwidth, Single Threaded and Parallelized + + + + + + + + +
+ +
+ + + Test workload: NASA Parallel Benchmark + + NASA Parallel Benchmark (NPB) is a small set of + compute-intensive kernels designed to evaluate the performance of supercomputers. They are + small compute kernels derived from Computational Fluid Dynamics + (CFD) applications. The problem size can be adjusted for different memory + sizes. Reference implementations exist for both MPI and OpenMP. This setup will focus on the + MPI reference implementation. + + While each application behaves differently, one common characteristic is that the + workload is very context-switch intensive, barriers frequently yield the CPU to other tasks + and the lifetime of individual processes can be very short-lived. The following paragraphs + detail the tuning selected for this workload. + + The most basic step is setting the CPU governor to performance although + it is not mandatory. This can address issues with short-lived or mobile tasks failing to + run long enough for a higher P-State to be selected even though the workload is very + throughput-sensitive. The migration cost parameter is set to reduce the frequency in which + the load balancer will move an individual task. The minimum granularity is adjusted to reduce + overscheduling effects. + + Depending on the computational kernel used, the workload may require a power-of-two + number or a square number of processes to be used. However, note that using all available + CPUs can mean that the application can contend with itself for CPU time. Furthermore, as IO + may be issued to shared memory backed by disk, there are system threads that also need CPU + time. Finally, if there is CPU contention, MPI tasks can be stalled waiting on an available + CPU and OpenMPI may yield tasks prematurely if it detects there are more MPI tasks than CPUs + available. These factors should be carefully considered when tuning for parallelized + workloads in general and MPI workloads in particular. + + In the specific case of testing NPB on the System Under Test, there was usually a limited + advantage to limiting the number of CPUs used. For the Embarrassingly Parallel (EP) load in particular, it benefits from using all + available CPUs. Hence, the default configuration used all available CPUs (512) which is both + a power-of-two and square number of CPUs because it was a sensible starting point. However, + this is not universally true. Using perf, it was found that some + workloads are memory-bound and do not benefit from a high degree of parallelization. In + addition, for the final configuration, some workloads were parallelized to have one task per + L3 cache in the system to maximize cache usage. The exception was the Scalar Pentadiagonal (SP) workload which was both memory-bound + and benefited from using all available CPUs. As the number of cores can vary between chips + and the number of populated memory channels, the tuning parameters used for this test may + not be universally true for all AMD EPYC platforms. This highlights that there is no + universal good choice for optimizing a workload for a platform. Thus, experimentation and + validation of tuning parameters is vital. + + The basic compilation flags simply turned on all safe optimizations. The + tuned flags used -Ofast which can be unsafe for some + mathematical workloads but generated the correct output for NPB. The other + flags used the optimal instructions available on the distribution compiler and + vectorized some operations. GCC 13 is more strict in terms + of matching types in Fortran. Depending on the version of NPB used, it may + be necessary to specify the -fallow-argument-mismatch + or -fallow-invalid-boz to compile unless the source code + is modified. + + As NPB uses shared files, an XFS partition was used for the temporary files. It is, + however, only used for mapping shared files and is not a critical path for the benchmark and + no IO tuning is necessary. In some cases, with MPI applications, it will be possible to use a + tmpfs partition for OpenMPI. This avoids unnecessary IO assuming the + increased physical memory usage does not cause the application to be paged out. + + + Test workload: NASA Parallel Benchmark + + + + + + + Compiler + + + gcc-13 (SUSE Linux) 13.2.1 + + + + + OpenMPI + + + openmpi4-4.1.6-150600.1.6.x86_64 + + + + + Default compiler flags + + + + -m64 -O3 -mcmodel=large + + + + + + Default number processes + + + + 512 + + + + + + Selective number processes + + + + bt=256 cg=256 ep=512 lu=256 mg=256 sp=256 + + + + + + Fortran compiler flags + + + + -fallow-argument-mismatch -fallow-invalid-boz + + + + + + Tuned compiler flags + + + + -Ofast -march=znver4 -mtune=znver4 -ftree-vectorize + + + + + + CPU governor performance + + + + cpupower frequency-set -g performance + + + + + + mpirun parameters + + + + -mca btl ^openib,udapl -np 512 --bind-to l3cache + + + + + + mpirun environment + + + + TMPDIR=/xfs-data-partition + + + + + +
+ + shows the time, as reported by + the benchmark, for each of the kernels to complete. + +
+ NAS MPI Results + + + + + + + + +
+ + + The gcc-7-default test used the system + compiler, all available CPUs, basic compilation options and the + performance governor. The second test gcc-13-default used an alternative compiler. gcc-13-tuned used additional compilation options, and + bound tasks to L3 caches gaining between 1.5% and 40.6% performance on average + relative to gcc-7-default. The final test + selective used processes that either used + all CPUs, avoided heavy overloaded or limited processes to one per L3 cache, + showing additional between 2.35% and 37.66% depending on the computational + kernel. + + In some cases, it will be necessary to compile an application that can run + on different CPUs. In such cases, -march=znver4 + may not be suitable if it generates binaries that are incompatible with other + vendors. In such cases, it is possible to specify the ISA-specific options that are + cross-compatible with many x86-based CPUs such as -mavx2, + -mfma, -msse2 or + msse4a while favoring optimal code generation for AMD + EPYC 9005 Series Processors with -mtune=znver4. This can be + used to strike a balance between excellent performance on a single CPU and great + performance on multiple CPUs. +
+ +
+ + + Tuning AMD EPYC 9005 Series Dense + + As the AMD EPYC 9005 Series Classic and AMD EPYC Series Dense are ISA-compatible, + no code tuning or compiler setting changes should be necessary. For Cloud environments, + partitioning or any binding of Virtual CPUs to Physical CPUs may need to be adjusted + to account for the increased number of cores. The additional cores may also allow + additional containers or virtual machines to be hosted on the same physical machine + without CPU contention. Similarly, the degree of parallelization for HPC workloads + may need to be adjusted. In cases where the workload is tuned based on the number of + CCD's, adjustments may be necessary for the changed number of CCDs. An exception are cases + where the workload already hits scaling limits. While tuning based on the different + number of CCXs is possible, it should only be necessary for applications with very + strict latency requirements. As the size of the cache per core is halved, partitioning based + on cache sizes may also need to be adjusted. In some cases, where workloads are tuned + based on the output of tools like hwloc partitioning + + may adjust automatically but any static partitioning should be re-examined. + + When configuring workloads for either the AMD EPYC 9005 Series Classic or the AMD + EPYC 9005 Series Dense, the most important task is to set expectations. While super-linear + scaling is possible, it should not be expected. It may be possible to achieve super-linear + scaling in Cloud Environments for the number of instances hosted without performance + loss if individual containers or virtual machines are not utilising 100% of CPU. However, + it should be planned carefully and tested. This would be particularly true in cases + where multiple instances are hosted that have different times of day or year for active + phases. The normal expectation is a best case of 33% gain for CPU-intensive workloads + due to the increased number of cores. But sub-linear scaling is common due to resource + contention. Contention between SMT siblings, memory bandwidth, memory availability, + memory interconnects, thread communication overhead or peripheral devices may prevent + perfect linear scaling even for perfectly parallelized applications. Similarly, not all + applications can scale perfectly. It is possible for performance to plateau and even + regress as the degree of parallelization increases. + + + + + Performance Monitoring Unit changes + Support for the following Zen related perf changes are present in SUSE Linux Enterprise 15 SP6: + + + AMD Performance Monitoring V2 (PerfMonV2) (v5.19) Zen4+ + + + global registers allowing enabling/disabling of multiple counters concurrently (via a single MSR operation) + + + dynamic detection of avalable PMUs + + + + + + AMD Zen4 IBS extensions (v5.19 kernel, v6.0 perf userspace) Zen4+ + + + DataSrc extension allowing the source of data to be decoded.Perf script and perf record (raw trace) will now report DataSrc details for tagged load/store operations. See perf-amd-ibs(1) for more details. + + + IBS L3 miss filtering.Enabled by specifying an l3missonly=1 event parameter to perf. See perf-amd-ibs(1) for more details. + + + + + + Last Branch Record Extension v2 (LbrExtV2) (v6.1) Zen4+ + + + LBR Freeze on PMI + + + Hardware branch filtering providing additional specificity + + + Branch speculation information + + + + + + JSON event file updates for Zen 4 (v6.2 perf userspace) Zen4+ + + + This adds event information from the "Core Performance Monitor", "L3 Cache Performance Monitor", "Fabric Performance Monitor Counter" and "Performance Measurement" sections of the AMD Processor Programming Reference (PPR) documentation for Zen4. + + + + + + Please note. Zen5 JSON event updates (perf userspace) were added in Linux v6.10 and will be supported in a subsequent SLE release. Support for Zen 4 unified memory controller events (kernel and perf userspace) is expected to be available in a similar timeframe. + + + + Conclusion + + The introduction of the AMD EPYC 9005 Series Classic and AMD EPYC 9005 Series Dense + Processors continues to push the boundaries of what is possible for memory and + IO-bound workloads with much higher bandwidth and available number of channels. A + properly configured and tuned workload can exceed the performance of many contemporary + off-the-shelf solutions even when fully customized. The symmetric and balanced nature + of the machine makes the task of tuning a workload considerably easier, given that + each partition can have symmetric performance. And this is a property that can turn + out particularly handy in virtualization, as each virtual machine can be assigned + to each one of the partitions. + + With SUSE Linux Enterprise 15 SP6, all the tools to monitor and tune a workload + are readily available. You can extract the maximum performance and + reliability running your applications on the 5th Generation AMD EPYC Processor + platform. + + + + + + + + Resources + + For more information, refer to: + + + + AMD EPYC 9005 Series Architecture Overview () + + + AMD Socket SP5 Power and Performance Optimization Guide for Family 1Ah Models 00h–0Fh and 10h–1Fh () + + + Optimizing Linux for Dual-Core AMD Opteron Processors () + + + Advanced Optimization and New Capabilities of GCC 12 () + + + Advanced Optimization and New Capabilities of GCC 11 () + + + Systems Performance: Enterprise and the Cloud by Brendan Gregg 2nd Edition() + + + NASA Parallel Benchmark () + + + + + + + + + + + + + + + + + + +