Docs: refactor and integrate into ROCm docs portal (#362)

* pip-compile docs/requirements.txt

Signed-off-by: Peter Jun Park <peter.park@amd.com>

Add Sphinx docs config

Signed-off-by: Peter Jun Park <peter.park@amd.com>

Add Sphinx config

Signed-off-by: Peter Jun Park <peter.park@amd.com>

Update docs build config

Signed-off-by: Peter Jun Park <peter.park@amd.com>

* style(conf.py): Apply black formatting to docs/conf.py

Signed-off-by: Sam Wu <22262939+samjwu@users.noreply.github.com>

* Update docs requirements

Signed-off-by: Peter Jun Park <peter.park@amd.com>

Update to rocm-docs-core 1.3.0

Signed-off-by: Peter Jun Park <peter.park@amd.com>

Update docs requirements

Signed-off-by: Peter Jun Park <peter.park@amd.com>

pip-compile requirements

Signed-off-by: Peter Jun Park <peter.park@amd.com>

bump rocm-docs-core to 1.5.0

bump rocm-docs-core to 1.4.1

Signed-off-by: Peter Jun Park <peter.park@amd.com>

* Add dependabot.yml and update CODEOWNERS

Signed-off-by: Peter Jun Park <peter.park@amd.com>

Update toc and conf

Signed-off-by: Peter Jun Park <peter.park@amd.com>

update dependabot

* Port docs to rocm-docs standard

Signed-off-by: Peter Jun Park <peter.park@amd.com>

Add toc and Diataxis cards

Signed-off-by: Peter Jun Park <peter.park@amd.com>

Add basic file structure

Signed-off-by: Peter Jun Park <peter.park@amd.com>

add glossary

Signed-off-by: Peter Jun Park <peter.park@amd.com>

add includes

Signed-off-by: Peter Jun Park <peter.park@amd.com>

Add license.rst

Signed-off-by: Peter Jun Park <peter.park@amd.com>

add compatible hw

Signed-off-by: Peter Jun Park <peter.park@amd.com>

fix spelling and license

Signed-off-by: Peter Jun Park <peter.park@amd.com>

clean up index

Signed-off-by: Peter Jun Park <peter.park@amd.com>

clean up installation guides

Signed-off-by: Peter Jun Park <peter.park@amd.com>

add basic usage (quickstart)

Signed-off-by: Peter Jun Park <peter.park@amd.com>

add ref to global options

update toc

Signed-off-by: Peter Jun Park <peter.park@amd.com>

modularize modes and global options

Signed-off-by: Peter Jun Park <peter.park@amd.com>

add profile mode

Signed-off-by: Peter Jun Park <peter.park@amd.com>

fixes

Signed-off-by: Peter Jun Park <peter.park@amd.com>

reorg and clean up

Signed-off-by: Peter Jun Park <peter.park@amd.com>

add dynamic omniperf version number in installation guide

Signed-off-by: Peter Jun Park <peter.park@amd.com>

add datatemplate

more reorg

Signed-off-by: Peter Jun Park <peter.park@amd.com>

clean up

Signed-off-by: Peter Jun Park <peter.park@amd.com>

reorg images

move profile mode

reorg

reorg

reorg more

fix formatting

fix headings

ref anchor mi2xx note

add extlinks

add extlinks

Signed-off-by: Peter Jun Park <peter.park@amd.com>

black format

fix formatting, anchors

Signed-off-by: Peter Jun Park <peter.park@amd.com>

reorg

fix words and formatting

Signed-off-by: Peter Jun Park <peter.park@amd.com>

formatting

Signed-off-by: Peter Jun Park <peter.park@amd.com>

same

reorg

format

fix formatting

fix toc

Signed-off-by: Peter Jun Park <peter.park@amd.com>

format

* impr internal linking and fix sphinx warnings

Signed-off-by: Peter Jun Park <peter.park@amd.com>

* add spellcheck/linting from rocm-docs-core

Signed-off-by: Peter Jun Park <peter.park@amd.com>

fix rst directives

satisfy spellcheck

fix more spelling

rm unused files

fix spelling and update wordlist

* bump rocm-docs-core to 1.6.0

Signed-off-by: Peter Jun Park <peter.park@amd.com>

* add fixes from @skyreflectedinmirrors and @lpaoletti

Signed-off-by: Peter Jun Park <peter.park@amd.com>

add references to toc

Signed-off-by: Peter Jun Park <peter.park@amd.com>

add more fixes

Signed-off-by: Peter Jun Park <peter.park@amd.com>

* add package manager install section

Signed-off-by: Peter Jun Park <peter.park@amd.com>

* add fixes

Signed-off-by: Peter Jun Park <peter.park@amd.com>

add metadata and fixes

Signed-off-by: Peter Jun Park <peter.park@amd.com>

add fixes

bump to 1.6.1

more fixes

fix fmt in profiling examples

Signed-off-by: Peter Jun Park <peter.park@amd.com>

add missing mem type table

Signed-off-by: Peter Jun Park <peter.park@amd.com>

fix formatting

fmt

* add custom css

Signed-off-by: Peter Jun Park <peter.park@amd.com>

fix css fs

* make images/figs click-to-expand

Signed-off-by: Peter Jun Park <peter.park@amd.com>

add missed image

update

fix link

* update documentation link in README

Signed-off-by: Peter Jun Park <peter.park@amd.com>

* formatting fixes

Signed-off-by: Peter Jun Park <peter.park@amd.com>

more formatting

* fix heading

Signed-off-by: Peter Jun Park <peter.park@amd.com>

* move archived docs

Signed-off-by: Peter Jun Park <peter.park@amd.com>

* exclude archived docs from docs build

Signed-off-by: Peter Jun Park <peter.park@amd.com>

* update archived docs workflow

Signed-off-by: Peter Jun Park <peter.park@amd.com>

move files

update archived docs workflow

Signed-off-by: Peter Jun Park <peter.park@amd.com>

fix version number

clean up workflow

workflow test

workflow test

another workflow test

* rm docs linting

Signed-off-by: Peter Jun Park <peter.park@amd.com>

* Apply cmake-format suggested changes

Signed-off-by: Sam Wu <22262939+samjwu@users.noreply.github.com>

* Apply cmake-format

Signed-off-by: Sam Wu <22262939+samjwu@users.noreply.github.com>

---------

Signed-off-by: Peter Jun Park <peter.park@amd.com>
Signed-off-by: Sam Wu <22262939+samjwu@users.noreply.github.com>
Co-authored-by: Sam Wu <22262939+samjwu@users.noreply.github.com>
This commit is contained in:
Peter Park
2024-07-31 10:42:27 -04:00
committed by David Galiffi
parent 96803e327c
commit a0dc485ceb
307 changed files with 16783 additions and 34 deletions
+154
View File
@@ -0,0 +1,154 @@
.. meta::
:description: Omniperf performance model: Command processor (CP)
:keywords: Omniperf, ROCm, profiler, tool, Instinct, accelerator, command, processor, fetcher, packet processor, CPF, CPC
**********************
Command processor (CP)
**********************
The command processor (CP) is responsible for interacting with the AMDGPU kernel
driver -- the Linux kernel -- on the CPU and for interacting with user-space
HSA clients when they submit commands to HSA queues. Basic tasks of the CP
include reading commands (such as, corresponding to a kernel launch) out of
:hsa-runtime-pdf:`HSA queues <68>`, scheduling work to subsequent parts of the
scheduler pipeline, and marking kernels complete for synchronization events on
the host.
The command processor consists of two sub-components:
* :ref:`Fetcher <cpf-metrics>` (CPF): Fetches commands out of memory to hand
them over to the CPC for processing.
* :ref:`Packet processor <cpc-metrics>` (CPC): Micro-controller running the
command processing firmware that decodes the fetched commands and (for
kernels) passes them to the :ref:`workgroup processors <desc-spi>` for
scheduling.
Before scheduling work to the accelerator, the command processor can
first acquire a memory fence to ensure system consistency
(:hsa-runtime-pdf:`Section 2.6.4 <91>`). After the work is complete, the
command processor can apply a memory-release fence. Depending on the AMD CDNA™
accelerator under question, either of these operations *might* initiate a cache
write-back or invalidation.
Analyzing command processor performance is most interesting for kernels
that you suspect to be limited by scheduling or launch rate. The command
processor’s metrics therefore are focused on reporting, for example:
* Utilization of the fetcher
* Utilization of the packet processor, and decoding processing packets
* Stalls in fetching and processing
.. _cpf-metrics:
Command processor fetcher (CPF)
===============================
.. list-table::
:header-rows: 1
* - Metric
- Description
- Unit
* - CPF Utilization
- Percent of total cycles where the CPF was busy actively doing any work.
The ratio of CPF busy cycles over total cycles counted by the CPF.
- Percent
* - CPF Stall
- Percent of CPF busy cycles where the CPF was stalled for any reason.
- Percent
* - CPF-L2 Utilization
- Percent of total cycles counted by the CPF-:doc:`L2 <l2-cache>` interface
where the CPF-L2 interface was active doing any work. The ratio of CPF-L2
busy cycles over total cycles counted by the CPF-L2.
- Percent
* - CPF-L2 Stall
- Percent of CPF-:doc:`L2 <l2-cache>` L2 busy cycles where the CPF-L2
interface was stalled for any reason.
- Percent
* - CPF-UTCL1 Stall
- Percent of CPF busy cycles where the CPF was stalled by address
translation.
- Percent
.. _cpc-metrics:
Command processor packet processor (CPC)
========================================
.. list-table::
:header-rows: 1
* - Metric
- Description
- Unit
* - CPC Utilization
- Percent of total cycles where the CPC was busy actively doing any work.
The ratio of CPC busy cycles over total cycles counted by the CPC.
- Percent
* - CPC Stall
- Percent of CPC busy cycles where the CPC was stalled for any reason.
- Percent
* - CPC Packet Decoding Utilization
- Percent of CPC busy cycles spent decoding commands for processing.
- Percent
* - CPC-Workgroup Manager Utilization
- Percent of CPC busy cycles spent dispatching workgroups to the
:ref:`workgroup manager <desc-spi>`.
- Percent
* - CPC-L2 Utilization
- Percent of total cycles counted by the CPC-:doc:`L2 <l2-cache>` interface
where the CPC-L2 interface was active doing any work.
- Percent
* - CPC-UTCL1 Stall
- Percent of CPC busy cycles where the CPC was stalled by address
translation.
- Percent
* - CPC-UTCL2 Utilization
- Percent of total cycles counted by the CPC's :doc:`L2 <l2-cache>` address
translation interface where the CPC was busy doing address translation
work.
- Percent
+60
View File
@@ -0,0 +1,60 @@
.. meta::
:description: Omniperf performance model: Compute unit (CU)
:keywords: Omniperf, ROCm, profiler, tool, Instinct, accelerator, GCN, compute, unit, pipeline, workgroup, wavefront,
CDNA
*****************
Compute unit (CU)
*****************
The compute unit (CU) is responsible for executing a user's kernels on
CDNA™-based accelerators. All :ref:`wavefronts <desc-wavefront>` of a
:ref:`workgroup <desc-workgroup>` are scheduled on the same CU.
.. image:: ../data/performance-model/gcn_compute_unit.png
:align: center
:alt: AMD CDNA accelerator compute unit diagram
:width: 800
The CU consists of several independent execution pipelines and functional units.
The :doc:`/conceptual/pipeline-descriptions` section details the various
execution pipelines -- VALU, SALU, LDS, scheduler, and so forth. The metrics
presented by Omniperf for these pipelines are described in
:doc:`pipeline-metrics`. The :doc:`vL1D <vector-l1-cache>` cache and
:doc:`LDS <local-data-share>` are described in their own sections.
* The :ref:`desc-valu` is composed of multiple SIMD (single
instruction, multiple data) vector processors, vector general purpose
registers (VGPRs) and instruction buffers. The VALU is responsible for
executing much of the computational work on CDNA accelerators, including but
not limited to floating-point operations (FLOPs) and integer operations
(IOPs).
* The vector memory (VMEM) unit is responsible for issuing loads, stores and
atomic operations that interact with the memory system.
* The :ref:`desc-salu` is shared by all threads in a
:ref:`wavefront <desc-wavefront>`, and is responsible for executing
instructions that are known to be uniform across the wavefront at compile
time. The SALU has a memory unit (SMEM) for interacting with memory, but it
cannot issue separately from the SALU.
* The :doc:`local-data-share` is an on-CU software-managed scratchpad memory
that can be used to efficiently share data between all threads in a
:ref:`workgroup <desc-workgroup>`.
* The :ref:`desc-scheduler` is responsible for issuing and decoding instructions
for all the :ref:`wavefronts <desc-wavefront>` on the compute unit.
* The :doc:`vector L1 data cache (vL1D) <vector-l1-cache>` is the first level
cache local to the compute unit. On current CDNA accelerators, the vL1D is
write-through. The vL1D caches from multiple compute units are kept coherent
with one another through software instructions.
* CDNA accelerators -- that is, AMD Instinct™ MI100 and newer -- contain
specialized matrix-multiplication accelerator pipelines known as the
:ref:`desc-mfma`.
For a more in-depth description of a compute unit on a CDNA accelerator, see
:hip-training-pdf:`22` and :gcn-crash-course:`27`.
+152
View File
@@ -0,0 +1,152 @@
.. meta::
:description: Omniperf terminology and definitions
:keywords: Omniperf, ROCm, glossary, definitions, terms, profiler, tool,
Instinct, accelerator, AMD
***********
Definitions
***********
The following table briefly defines some terminology used in Omniperf interfaces
and in this documentation.
.. include:: ./includes/terms.rst
.. include:: ./includes/normalization-units.rst
.. _memory-spaces:
Memory spaces
=============
AMD Instinct™ MI-series accelerators can access memory through multiple address spaces
which may map to different physical memory locations on the system. The
following table provides a view into how various types of memory used
in HIP map onto these constructs:
.. list-table::
:header-rows: 1
* - LLVM Address Space
- Hardware Memory Space
- HIP Terminology
* - Generic
- Flat
- N/A
* - Global
- Global
- Global
* - Local
- LDS
- LDS/Shared
* - Private
- Scratch
- Private
* - Constant
- Same as global
- Constant
The following is a high-level description of the address spaces in the AMDGPU
backend of LLVM:
.. list-table::
:header-rows: 1
* - Address space
- Description
* - Global
- Memory that can be seen by all threads in a process, and may be backed by
the local accelerator's HBM, a remote accelerator's HBM, or the CPU's
DRAM.
* - Local
- Memory that is only visible to a particular workgroup. On AMD's Instinct
accelerator hardware, this is stored in :doc:`LDS <local-data-share>`
memory.
* - Private
- Memory that is only visible to a particular [work-item](workitem)
(thread), stored in the scratch space on AMD's Instinct accelerators.
* - Constant
- Read-only memory that is in the global address space and stored on the
local accelerator's HBM.
* - Generic
- Used when the compiler cannot statically prove that a pointer is
addressing memory in a single (non-generic) address space. Mapped to Flat
on AMD's Instinct accelerators, the pointer could dynamically address
global, local, private or constant memory.
`LLVM's documentation for AMDGPU Backend <https://llvm.org/docs/AMDGPUUsage.html#address-spaces>`_
has the most up-to-date information. Refer to this source for a more complete
explanation.
.. _memory-type:
Memory type
===========
AMD Instinct accelerators contain a number of different memory allocation
types to enable the HIP language's
:doc:`memory coherency model <hip:how-to/programming_manual>`.
These memory types are broadly similar between AMD Instinct accelerator
generations, but may differ in exact implementation.
In addition, these memory types *might* differ between accelerators on the same
system, even when accessing the same memory allocation.
For example, an :ref:`MI2XX <mixxx-note>` accelerator accessing *fine-grained*
memory allocated local to that device may see the allocation as coherently
cacheable, while a remote accelerator might see the same allocation as
*uncached*.
These memory types include:
.. list-table::
:header-rows: 1
* - Memory type
- Description
* - Uncached Memory (UC)
- Memory that will not be cached in this accelerator. On
:ref:`MI2XX <mixxx-note>` accelerators, this corresponds “fine-grained”
(or, “coherent”) memory allocated on a remote accelerator or the host,
for example, using ``hipHostMalloc`` or ``hipMallocManaged`` with default
allocation flags.
* - Non-hardware-Coherent Memory (NC)
- Memory that will be cached by the accelerator, and is only guaranteed to
be consistent at kernel boundaries / after software-driven
synchronization events. On :ref:`MI2XX <mixxx-note>` accelerators, this
type of memory maps to, for example, “coarse-grained” ``hipHostMalloc``’d
memory -- that is, allocated with the ``hipHostMallocNonCoherent``
flag -- or ``hipMalloc``’d memory allocated on a remote accelerator.
* - Coherently Cachable (CC)
- Memory for which only reads from the accelerator where the memory was
allocated will be cached. Writes to CC memory are uncached, and trigger
invalidations of any line within this accelerator. On
:ref:`MI2XX <mixxx-note>` accelerators, this type of memory maps to
“fine-grained” memory allocated on the local accelerator using, for
example, the ``hipExtMallocWithFlags`` API using the
``hipDeviceMallocFinegrained`` flag.
* - Read/Write Coherent Memory (RW)
- Memory that will be cached by the accelerator, but may be invalidated by
writes from remote devices at kernel boundaries / after software-driven
synchronization events. On :ref:`MI2XX <mixxx-note>` accelerators, this
corresponds to “coarse-grained” memory allocated locally to the
accelerator, using for example, the default ``hipMalloc`` allocator.
Find a good discussion of coarse and fine-grained memory allocations and what
type of memory is returned by various combinations of memory allocators, flags
and arguments in the
`Crusher quick-start guide <https://docs.olcf.ornl.gov/systems/crusher_quick_start_guide.html#floating-point-fp-atomic-operations-and-coarse-fine-grained-memory-allocations>`_.
@@ -0,0 +1,47 @@
.. _normalization-units:
Normalization units
===================
A user-configurable unit by which you can choose to normalize data. Options
include:
.. list-table::
:header-rows: 1
* - Name
- Description
* - ``per_wave``
- The total value of the measured counter or metric that occurred per
kernel invocation divided by the total number of
:ref:`wavefronts <desc-wavefront>` launched in the kernel.
* - ``per_cycle``
- The total value of the measured counter or metric that occurred per
kernel invocation divided by the
:ref:`kernel cycles <kernel-cycles>`, that is, the total number of
cycles the kernel executed as measured by the
:doc:`command processor <command-processor>`.
* - ``per_kernel``
- The total value of the measured counter or metric that occurred per
kernel invocation.
* - ``per_second``
- The total value of the measured counter or metric that occurred per
kernel invocation divided by the :ref:`kernel time <kernel-time>`,
that is, the total runtime of the kernel in seconds, as measured by the
:doc:`command processor <command-processor>`.
By default, Omniperf uses the ``per_wave`` normalization.
.. tip::
The best normalization may vary depending on your use case. For instance, a
``per_second`` normalization might be useful for FLOP or bandwidth
comparisons, while a ``per_wave`` normalization could be useful to see how many
(and what types) of instructions are used per wavefront. A ``per_kernel``
normalization can be useful to get the total aggregate values of metrics for
comparison between different configurations.
+188
View File
@@ -0,0 +1,188 @@
.. _desc-workgroup:
.. _desc-work-item:
.. _desc-wavefront:
.. _desc-divergence:
.. _kernel-time:
.. _kernel-cycles:
.. _total-active-cu-cycles:
.. _total-cu-cycles:
.. _total-se-cycles:
.. _total-simd-cycles:
.. _total-pipe-cycles:
.. _total-l1i-cycles:
.. _total-active-l2-cycles:
.. _total-l2-cycles:
.. _total-sl1d-cycles:
.. _thread-requests:
.. list-table::
:header-rows: 1
* - Name
- Description
- Unit
* - Kernel time
- The number of seconds the accelerator was executing a kernel, from the
:doc:`command processor <command-processor>`'s (CP) start-of-kernel
timestamp (a number of cycles after the CP beings processing the packet)
to the CP's end-of-kernel timestamp (a number of cycles before the CP
stops processing the packet).
- Seconds
* - Kernel cycles
- The number of cycles the accelerator was active doing *any* work, as
measured by the :doc:`command processor <command-processor>` (CP).
- Cycles
* - Total CU cycles
- The number of cycles the accelerator was active doing *any* work
(that is, kernel cycles), multiplied by the number of
:doc:`compute units <compute-unit>` on the accelerator. A
measure of the total possible active cycles the compute units could be
doing work, useful for the normalization of metrics inside the CU.
- Cycles
* - Total active CU cycles
- The number of cycles a CU on the accelerator was active doing *any*
work, summed over all :doc:`compute units <compute-unit>` on the
accelerator.
- Cycles
* - Total SIMD cycles
- The number of cycles the accelerator was active doing *any* work (that
is, kernel cycles), multiplied by the number of
:doc:`SIMDs <compute-unit>` on the accelerator. A measure of the
total possible active cycles the SIMDs could be doing work, useful for
the normalization of metrics inside the CU.
- Cycles
* - Total L2 cycles
- The number of cycles the accelerator was active doing *any* work (that
is, kernel cycles), multiplied by the number of :doc:`L2 <l2-cache>`
channels on the accelerator. A measure of the total possible active
cycles the L2 channels could be doing work, useful for the normalization
of metrics inside the L2.
- Cycles
* - Total active L2 cycles
- The number of cycles a channel of the L2 cache was active doing *any*
work, summed over all :doc:`L2 <l2-cache>` channels on the accelerator.
- Cycles
* - Total sL1D cycles
- The number of cycles the accelerator was active doing *any* work (that
is, kernel cycles), multiplied by the number of
:ref:`scalar L1 data caches <desc-sl1d>` on the accelerator. A measure of
the total possible active cycles the sL1Ds could be doing work, useful
for the normalization of metrics inside the sL1D.
- Cycles
* - Total L1I cycles
- The number of cycles the accelerator was active doing *any* work (that
is, kernel cycles), multiplied by the number of
:ref:`L1 instruction caches <desc-l1i>` (L1I) on the accelerator. A
measure of the total possible active cycles the L1Is could be doing
work, useful for the normalization of metrics inside the L1I.
- Cycles
* - Total scheduler-pipe cycles
- The number of cycles the accelerator was active doing *any* work (that
is, kernel cycles), multiplied by the number of
:doc:`scheduler pipes <command-processor>` on the accelerator. A measure
of the total possible active cycles the scheduler-pipes could be doing
work, useful for the normalization of metrics inside the
:ref:`workgroup manager <desc-spi>` and
:doc:`command processor <command-processor>`.
- Cycles
* - Total shader-engine cycles
- The total number of cycles the accelerator was active doing *any* work,
multiplied by the number of :doc:`shader engines <shader-engine>` on the
accelerator. A measure of the total possible active cycles the shader
engines could be doing work, useful for the normalization of
metrics inside the :ref:`workgroup manager <desc-spi>`.
- Cycles
* - Thread-requests
- The number of unique memory addresses accessed by a single memory
instruction. On AMD Instinct accelerators, this has a maximum of 64
(that is, the size of the :ref:`wavefront <wavefront>`).
- Addresses
* - Work-item
- A single *thread*, or lane, of execution that executes in lockstep with
the rest of the work-items comprising a :ref:`wavefront <wavefront>`
of execution.
- N/A
* - Wavefront
- A group of work-items, or threads, that execute in lockstep on the
:doc:`compute unit <compute-unit>`. On AMD Instinct accelerators, the
wavefront size is always 64 work-items.
- N/A
* - Workgroup
- A group of wavefronts that execute on the same
:doc:`compute unit <compute-unit>`, and can cooperatively execute and
share data via the use of synchronization primitives,
:doc:`LDS <local-data-share>`, atomics, and others.
- N/A
* - Divergence
- Divergence within a wavefront occurs when not all work-items are active
when executing an instruction, that is, due to non-uniform control flow
within a wavefront. Can reduce execution efficiency by causing,
for instance, the :ref:`VALU <desc-valu>` to need to execute both
branches of a conditional with different sets of work-items active.
- N/A
+776
View File
@@ -0,0 +1,776 @@
.. meta::
:description: Omniperf performance model: L2 cache (TCC)
:keywords: Omniperf, ROCm, profiler, tool, Instinct, accelerator, L2, cache, infinity fabric, metrics
**************
L2 cache (TCC)
**************
The L2 cache is the coherence point for current AMD Instinct™ MI-series GCN™
GPUs and CDNA™ accelerators, and is shared by all :doc:`CUs <compute-unit>`
on the device. Besides serving requests from the
:doc:`vector L1 data caches <vector-l1-cache>`, the L2 cache also is responsible
for servicing requests from the :ref:`L1 instruction caches <desc-l1i>`, the
:ref:`scalar L1 data caches <desc-sL1D>` and the
:doc:`command processor <command-processor>`. The L2 cache is composed of a
number of distinct channels (32 on MI100 and :ref:`MI2XX <mixxx-note>` series CDNA
accelerators at 256B address interleaving) which can largely operate
independently. Mapping of incoming requests to a specific L2 channel is
determined by a hashing mechanism that attempts to evenly distribute requests
across the L2 channels. Requests that miss in the L2 cache are passed out to
:ref:`Infinity Fabric™ <l2-fabric>` to be routed to the appropriate memory
location.
The L2 cache metrics reported by Omniperf are broken down into four
categories:
* :ref:`L2 Speed-of-Light <l2-sol>`
* :ref:`L2 cache accesses <l2-cache-accesses>`
* :ref:`L2-Fabric transactions <l2-fabric>`
* :ref:`L2-Fabric stalls <l2-fabric-stalls>`
.. _l2-sol:
L2 Speed-of-Light
=================
.. warning::
The theoretical maximum throughput for some metrics in this section
are currently computed with the maximum achievable clock frequency, as
reported by ``rocminfo``, for an accelerator. This may not be realistic for
all workloads.
The L2 cache’s speed-of-light table contains a few key metrics about the
performance of the L2 cache, aggregated over all the L2 channels, as a
comparison with the peak achievable values of those metrics:
.. list-table::
:header-rows: 1
* - Metric
- Description
- Unit
* - Utilization
- The ratio of the
:ref:`number of cycles an L2 channel was active, summed over all L2 channels on the accelerator <total-active-l2-cycles>`
over the :ref:`total L2 cycles <total-l2-cycles>`.
- Percent
* - Bandwidth
- The number of bytes looked up in the L2 cache, as a percent of the peak
theoretical bandwidth achievable on the specific accelerator. The number
of bytes is calculated as the number of cache lines requested multiplied
by the cache line size. This value does not consider partial requests, so
e.g., if only a single value is requested in a cache line, the data
movement will still be counted as a full cache line.
- Percent
* - Hit Rate
- The ratio of the number of L2 cache line requests that hit in the L2
cache over the total number of incoming cache line requests to the L2
cache.
- Percent
* - L2-Fabric Read BW
- The number of bytes read by the L2 over the
:ref:`Infinity Fabric interface <l2-fabric>` per unit time.
- GB/s
* - L2-Fabric Write and Atomic BW
- The number of bytes sent by the L2 over the
:ref:`Infinity Fabric interface <l2-fabric>` by write and atomic
operations per unit time.
- GB/s
.. note::
The L2 cache on AMD Instinct MI CDNA accelerators uses a "hit-on-miss"
approach to reporting cache hits. That is, if while satisfying a miss,
another request comes in that would hit on the same pending cache line, the
subsequent request will be counted as a 'hit'. Therefore, it is also
important to consider the latency metric in the :ref:`L2-Fabric <l2-fabric>`
section when evaluating the L2 hit rate.
.. _l2-cache-accesses:
L2 cache accesses
=================
This section details the incoming requests to the L2 cache from the
:doc:`vL1D <vector-l1-cache>` and other clients -- for instance, the
:ref:`sL1D <desc-sL1D>` and :ref:`L1I <desc-l1i>` caches.
.. list-table::
:header-rows: 1
:widths: 13 70 17
* - Metric
- Description
- Unit
* - Bandwidth
- The number of bytes looked up in the L2 cache, per
:ref:`normalization unit <normalization-units>`. The number of bytes is
calculated as the number of cache lines requested multiplied by the cache
line size. This value does not consider partial requests, so for example,
if only a single value is requested in a cache line, the data movement
will still be counted as a full cache line.
- Bytes per :ref:`normalization unit <normalization-units>`.
* - Requests
- The total number of incoming requests to the L2 from all clients for all
request types, per :ref:`normalization unit <normalization-units>`.
- Requests per :ref:`normalization unit <normalization-units>`.
* - Read Requests
- The total number of read requests to the L2 from all clients.
- Requests per :ref:`normalization unit <normalization-units>`
* - Write Requests
- The total number of write requests to the L2 from all clients.
- Requests per :ref:`normalization unit <normalization-units>`
* - Atomic Requests
- The total number of atomic requests (with and without return) to the L2
from all clients.
- Requests per :ref:`normalization unit <normalization-units>`
* - Streaming Requests
- The total number of incoming requests to the L2 that are marked as
*streaming*. The exact meaning of this may differ depending on the
targeted accelerator, however on an :ref:`MI2XX <mixxx-note>` this
corresponds to
`non-temporal load or stores <https://clang.llvm.org/docs/LanguageExtensions.html#non-temporal-load-store-builtins>`_.
The L2 cache attempts to evict *streaming* requests before normal
requests when the L2 is at capacity.
- Requests per :ref:`normalization unit <normalization-units>`
* - Probe Requests
- The number of coherence probe requests made to the L2 cache from outside
the accelerator. On an :ref:`MI2XX <mixxx-note>`, probe requests may be
generated by, for example, writes to
:ref:`fine-grained device <memory-type>` memory or by writes to
:ref:`coarse-grained <memory-type>` device memory.
- Requests per :ref:`normalization unit <normalization-units>`
* - Hit Rate
- The ratio of the number of L2 cache line requests that hit in the L2
cache over the total number of incoming cache line requests to the L2
cache.
- Percent
* - Hits
- The total number of requests to the L2 from all clients that hit in the
cache. As noted in the :ref:`Speed-of-Light <l2-sol>` section, this
includes hit-on-miss requests.
- Requests per :ref:`normalization unit <normalization-units>`
* - Misses
- The total number of requests to the L2 from all clients that miss in the
cache. As noted in the :ref:`Speed-of-Light <l2-sol>` section, these do
not include hit-on-miss requests.
- Requests per :ref:`normalization unit <normalization-units>`
* - Writebacks
- The total number of L2 cache lines written back to memory for any reason.
Write-backs may occur due to user code (such as HIP kernel calls to
``__threadfence_system`` or atomic built-ins) by the
:doc:`command processor <command-processor>`'s memory acquire/release
fences, or for other internal hardware reasons.
- Cache lines per :ref:`normalization unit <normalization-units>`
* - Writebacks (Internal)
- The total number of L2 cache lines written back to memory for internal
hardware reasons, per :ref:`normalization unit <normalization-units>`.
- Cache lines per :ref:`normalization unit <normalization-units>`.
* - Writebacks (vL1D Req)
- The total number of L2 cache lines written back to memory due to requests
initiated by the :doc:`vL1D cache <vector-l1-cache>`, per
:ref:`normalization unit <normalization-units>`.
- Cache lines per :ref:`normalization unit <normalization-units>`.
* - Evictions (Normal)
- The total number of L2 cache lines evicted from the cache due to capacity
limits, per :ref:`normalization unit <normalization-units>`.
- Cache lines per :ref:`normalization unit <normalization-units>`.
* - Evictions (vL1D Req)
- The total number of L2 cache lines evicted from the cache due to
invalidation requests initiated by the
:doc:`vL1D cache <vector-l1-cache>`, per
:ref:`normalization unit <normalization-units>`.
- Cache lines per :ref:`normalization unit <normalization-units>`.
* - Non-hardware-Coherent Requests
- The total number of requests to the L2 to Not-hardware-Coherent (NC)
memory allocations, per :ref:`normalization unit <normalization-units>`.
See the :ref:`memory-type` for more information.
- Requests per :ref:`normalization unit <normalization-units>`.
* - Uncached Requests
- The total number of requests to the L2 that go to Uncached (UC) memory
allocations. See the :ref:`memory-type` for more information.
- Requests per :ref:`normalization unit <normalization-units>`.
* - Coherently Cached Requests
- The total number of requests to the L2 that go to Coherently Cacheable (CC)
memory allocations. See the :ref:`memory-type` for more information.
- Requests per :ref:`normalization unit <normalization-units>`.
* - Read/Write Coherent Requests
- The total number of requests to the L2 that go to Read-Write coherent memory
(RW) allocations. See the :ref:`memory-type` for more information.
- Requests per :ref:`normalization unit <normalization-units>`.
.. note::
All requests to the L2 are for a single cache line's worth of data. The size
of a cache line may vary depending on the accelerator, however on an AMD
Instinct CDNA2 :ref:`MI2XX <mixxx-note>` accelerator, it is 128B, while on
an MI100, it is 64B.
.. _l2-fabric:
L2-Fabric transactions
======================
Requests/data that miss in the L2 must be routed to memory in order to
service them. The backing memory for a request may be local to this
accelerator (i.e., in the local high-bandwidth memory), in a remote
accelerator’s memory, or even in the CPU’s memory. Infinity Fabric
is responsible for routing these memory requests/data to the correct
location and returning any fetched data to the L2 cache. The
:ref:`l2-request-flow` describes the flow of these requests through
Infinity Fabric in more detail, as described by Omniperf metrics,
while :ref:`l2-request-metrics` give detailed definitions of
individual metrics.
.. _l2-request-flow:
Request flow
------------
The following is a diagram that illustrates how L2↔Fabric requests are reported
by Omniperf:
.. figure:: ../data/performance-model/fabric.png
:align: center
:alt: L2-Fabric transaction flow on AMD Instinct MI-series accelerators
:width: 800
L2↔Fabric transaction flow on AMD Instinct MI-series accelerators.
Requests from the L2 Cache are broken down into two major categories, read
requests and write requests (at this granularity, atomic requests are treated
as writes).
From there, these requests can additionally subdivided in a number of ways.
First, these requests may be sent across Infinity Fabric as different
transaction sizes, 32B or 64B on current CDNA accelerators.
.. note::
On current CDNA accelerators, the 32B read request path is expected to be
unused and so is disconnected in the flow diagram.
In addition, the read and write requests can be further categorized as:
* Uncached read/write requests, for instance: for access to
:ref:`fine-grained memory <memory-type>`
* Atomic requests, for instance: for atomic updates to
:ref:`fine-grained memory <memory-type>`
* HBM read/write requests OR remote read/write requests, for instance: for
requests to the accelerator’s local HBM OR requests to a remote accelerator’s
HBM or the CPU’s DRAM
These classifications are not necessarily *exclusive*. For example, a
write request can be classified as an atomic request to the
accelerator’s local HBM, and an uncached write request. The request-flow
diagram marks *exclusive* classifications as a splitting of the flow,
while *non-exclusive* requests do not split the flow line. For example,
a request is either a 32B Write Request OR a 64B Write request, as the
flow splits at this point:
.. figure:: ../data/performance-model/split.*
:align: center
:alt: Splitting request flow
:width: 800
Splitting request flow
However, continuing along, the same request might be an atomic request and an
uncached write request, as reflected by a non-split flow:
.. figure:: ../data/performance-model/nosplit.*
:align: center
:alt: Non-splitting request flow
:width: 800
Non-splitting request flow
Finally, we note that :ref:`uncached <memory-type>` read requests (e.g., to
:ref:`fine-grained memory <memory-type>`) are handled specially on CDNA
accelerators, as indicated in the request flow diagram. These are
expected to be counted as a 64B Read Request, and *if* they are requests
to uncached memory (denoted by the dashed line), they will also be
counted as *two* uncached read requests (that is, the request is split):
.. figure:: ../data/performance-model/uncached.*
:align: center
:alt: Uncached read-request splitting
:width: 800
Uncached read-request splitting.
.. _l2-request-metrics:
Metrics
-------
The following metrics are reported for the L2-Fabric interface:
.. list-table::
:header-rows: 1
* - Metric
- Description
- Unit
* - L2-Fabric Read Bandwidth
- The total number of bytes read by the L2 cache from Infinity Fabric per
:ref:`normalization unit <normalization-units>`.
- Bytes per :ref:`normalization unit <normalization-units>`.
* - HBM Read Traffic
- The percent of read requests generated by the L2 cache that are routed to
the accelerator's local high-bandwidth memory (HBM). This breakdown does
not consider the *size* of the request (meaning that 32B and 64B requests
are both counted as a single request), so this metric only *approximates*
the percent of the L2-Fabric Read bandwidth directed to the local HBM.
- Percent
* - Remote Read Traffic
- The percent of read requests generated by the L2 cache that are routed to
any memory location other than the accelerator's local high-bandwidth
memory (HBM) -- for example, the CPU's DRAM or a remote accelerator's
HBM. This breakdown does not consider the *size* of the request (meaning
that 32B and 64B requests are both counted as a single request), so this
metric only *approximates* the percent of the L2-Fabric Read bandwidth
directed to a remote location.
- Percent
* - Uncached Read Traffic
- The percent of read requests generated by the L2 cache that are reading
from an :ref:`uncached memory allocation <memory-type>`. Note, as
described in the :ref:`request flow <l2-request-flow>` section, a single
64B read request is typically counted as two uncached read requests. So,
it is possible for the Uncached Read Traffic to reach up to 200% of the
total number of read requests. This breakdown does not consider the
*size* of the request (i.e., 32B and 64B requests are both counted as a
single request), so this metric only *approximates* the percent of the
L2-Fabric read bandwidth directed to an uncached memory location.
- Percent
* - L2-Fabric Write and Atomic Bandwidth
- The total number of bytes written by the L2 over Infinity Fabric by write
and atomic operations per
:ref:`normalization unit <normalization-units>`. Note that on current
CDNA accelerators, such as the :ref:`MI2XX <mixxx-note>`, requests are
only considered *atomic* by Infinity Fabric if they are targeted at
non-write-cacheable memory, for example,
:ref:`fine-grained memory <memory-type>` allocations or
:ref:`uncached memory <memory-type>` allocations on the
MI2XX.
- Bytes per :ref:`normalization unit <normalization-units>`.
* - HBM Write and Atomic Traffic
- The percent of write and atomic requests generated by the L2 cache that
are routed to the accelerator's local high-bandwidth memory (HBM). This
breakdown does not consider the *size* of the request (meaning that 32B
and 64B requests are both counted as a single request), so this metric
only *approximates* the percent of the L2-Fabric Write and Atomic
bandwidth directed to the local HBM. Note that on current CDNA
accelerators, such as the :ref:`MI2XX <mixxx-note>`, requests are only
considered *atomic* by Infinity Fabric if they are targeted at
:ref:`fine-grained memory <memory-type>` allocations or
:ref:`uncached memory <memory-type>` allocations.
- Percent
* - Remote Write and Atomic Traffic
- The percent of read requests generated by the L2 cache that are routed to
any memory location other than the accelerator's local high-bandwidth
memory (HBM) -- for example, the CPU's DRAM or a remote accelerator's
HBM. This breakdown does not consider the *size* of the request (meaning
that 32B and 64B requests are both counted as a single request), so this
metric only *approximates* the percent of the L2-Fabric Read bandwidth
directed to a remote location. Note that on current CDNA
accelerators, such as the :ref:`MI2XX <mixxx-note>`, requests are only
considered *atomic* by Infinity Fabric if they are targeted at
:ref:`fine-grained memory <memory-type>` allocations or
:ref:`uncached memory <memory-type>` allocations.
- Percent
* - Atomic Traffic
- The percent of write requests generated by the L2 cache that are atomic
requests to *any* memory location. This breakdown does not consider the
*size* of the request (meaning that 32B and 64B requests are both counted
as a single request), so this metric only *approximates* the percent of
the L2-Fabric Read bandwidth directed to a remote location. Note that on
current CDNA accelerators, such as the :ref:`MI2XX <mixxx-note>`,
requests are only considered *atomic* by Infinity Fabric if they are
targeted at :ref:`fine-grained memory <memory-type>` allocations or
:ref:`uncached memory <memory-type>` allocations.
- Percent
* - Uncached Write and Atomic Traffic
- The percent of write and atomic requests generated by the L2 cache that
are targeting :ref:`uncached memory allocations <memory-type>`. This
breakdown does not consider the *size* of the request (meaning that 32B
and 64B requests are both counted as a single request), so this metric
only *approximates* the percent of the L2-Fabric read bandwidth directed
to uncached memory allocations.
- Percent
* - Read Latency
- The time-averaged number of cycles read requests spent in Infinity Fabric
before data was returned to the L2.
- Cycles
* - Write Latency
- The time-averaged number of cycles write requests spent in Infinity
Fabric before a completion acknowledgement was returned to the L2.
- Cycles
* - Atomic Latency
- The time-averaged number of cycles atomic requests spent in Infinity
Fabric before a completion acknowledgement (atomic without return value)
or data (atomic with return value) was returned to the L2.
- Cycles
* - Read Stall
- The ratio of the total number of cycles the L2-Fabric interface was
stalled on a read request to any destination (local HBM, remote PCIe®
connected accelerator or CPU, or remote Infinity Fabric connected
accelerator [#inf]_ or CPU) over the
:ref:`total active L2 cycles <total-active-l2-cycles>`.
- Percent
* - Write Stall
- The ratio of the total number of cycles the L2-Fabric interface was
stalled on a write or atomic request to any destination (local HBM,
remote accelerator or CPU, PCIe connected accelerator or CPU, or remote
Infinity Fabric connected accelerator [#inf]_ or CPU) over the
:ref:`total active L2 cycles <total-active-l2-cycles>`.
- Percent
.. _l2-detailed-metrics:
Detailed transaction metrics
----------------------------
The following metrics are available in the detailed L2-Fabric
transaction breakdown table:
.. list-table::
:header-rows: 1
* - Metric
- Description
- Unit
* - 32B Read Requests
- The total number of L2 requests to Infinity Fabric to read 32B of data
from any memory location, per
:ref:`normalization unit <normalization-units>`. See
:ref:`l2-request-flow` for more detail. Typically unused on CDNA
accelerators.
- Requests per :ref:`normalization unit <normalization-units>`.
* - Uncached Read Requests
- The total number of L2 requests to Infinity Fabric to read
:ref:`uncached data <memory-type>` from any memory location, per
:ref:`normalization unit <normalization-units>`. 64B requests for
uncached data are counted as two 32B uncached data requests. See
:ref:`l2-request-flow` for more detail.
- Requests per :ref:`normalization unit <normalization-units>`.
* - 64B Read Requests
- The total number of L2 requests to Infinity Fabric to read 64B of data
from any memory location, per
:ref:`normalization unit <normalization-units>`. See
:ref:`l2-request-flow` for more detail.
- Requests per :ref:`normalization unit <normalization-units>`.
* - HBM Read Requests
- The total number of L2 requests to Infinity Fabric to read 32B or 64B of
data from the accelerator's local HBM, per
:ref:`normalization unit <normalization-units>`. See
:ref:`l2-request-flow` for more detail.
- Requests per :ref:`normalization unit <normalization-units>`.
* - Remote Read Requests
- The total number of L2 requests to Infinity Fabric to read 32B or 64B of
data from any source other than the accelerator's local HBM, per
:ref:`normalization unit <normalization-units>`. See
:ref:`l2-request-flow` for more detail.
- Requests per :ref:`normalization unit <normalization-units>`.
* - 32B Write and Atomic Requests
- The total number of L2 requests to Infinity Fabric to write or atomically
update 32B of data to any memory location, per
:ref:`normalization unit <normalization-units>`. See
:ref:`l2-request-flow` for more detail.
- Requests per :ref:`normalization unit <normalization-units>`.
* - Uncached Write and Atomic Requests
- The total number of L2 requests to Infinity Fabric to write or atomically
update 32B or 64B of :ref:`uncached data <memory-type>`, per
:ref:`normalization unit <normalization-units>`. See
:ref:`l2-request-flow` for more detail.
- Requests per :ref:`normalization unit <normalization-units>`.
* - 64B Write and Atomic Requests
- The total number of L2 requests to Infinity Fabric to write or atomically
update 64B of data in any memory location, per
:ref:`normalization unit <normalization-units>`. See
:ref:`l2-request-flow` for more detail.
- Requests per :ref:`normalization unit <normalization-units>`.
* - HBM Write and Atomic Requests
- The total number of L2 requests to Infinity Fabric to write or atomically
update 32B or 64B of data in the accelerator's local HBM, per
:ref:`normalization unit <normalization-units>`. See
:ref:`l2-request-flow` for more detail.
- Requests per :ref:`normalization unit <normalization-units>`.
* - Remote Write and Atomic Requests
- The total number of L2 requests to Infinity Fabric to write or atomically
update 32B or 64B of data in any memory location other than the
accelerator's local HBM, per
:ref:`normalization unit <normalization-units>`. See
:ref:`l2-request-flow` for more detail.
- Requests per :ref:`normalization unit <normalization-units>`.
* - Atomic Requests
- The total number of L2 requests to Infinity Fabric to atomically update
32B or 64B of data in any memory location, per
:ref:`normalization unit <normalization-units>`. See
:ref:`l2-request-flow` for more detail. Note that on current CDNA
accelerators, such as the :ref:`MI2XX <mixxx-note>`, requests are only
considered *atomic* by Infinity Fabric if they are targeted at
non-write-cacheable memory, such as
:ref:`fine-grained memory <memory-type>` allocations or
:ref:`uncached memory <memory-type>` allocations on the MI2XX.
- Requests per :ref:`normalization unit <normalization-units>`.
.. _l2-fabric-stalls:
L2-Fabric interface stalls
==========================
When the interface between the L2 cache and Infinity Fabric becomes backed up by
requests, it may stall, preventing the L2 from issuing additional requests to
Infinity Fabric until prior requests complete. This section gives a breakdown of
what types of requests in a kernel caused a stall (like read versus write), and
to which locations -- for instance, to the accelerator’s local memory, or to
remote accelerators or CPUs.
.. list-table::
:header-rows: 1
* - Metric
- Description
- Unit
* - Read - PCIe Stall
- The number of cycles the L2-Fabric interface was stalled on read requests
to remote PCIe connected accelerators [#inf]_ or CPUs as a percent of the
:ref:`total active L2 cycles <total-active-l2-cycles>`.
- Percent
* - Read - Infinity Fabric Stall
- The number of cycles the L2-Fabric interface was stalled on read requests
to remote Infinity Fabric connected accelerators [#inf]_ or CPUs as a
percent of the :ref:`total active L2 cycles <total-active-l2-cycles>`.
- Percent
* - Read - HBM Stall
- The number of cycles the L2-Fabric interface was stalled on read requests
to the accelerator's local HBM as a percent of the
:ref:`total active L2 cycles <total-active-l2-cycles>`.
- Percent
* - Write - PCIe Stall
- The number of cycles the L2-Fabric interface was stalled on write or
atomic requests to remote PCIe connected accelerators [#inf]_ or CPUs as
a percent of the :ref:`total active L2 cycles <total-active-l2-cycles>`.
- Percent
* - Write - Infinity Fabric Stall
- The number of cycles the L2-Fabric interface was stalled on write or
atomic requests to remote Infinity Fabric connected accelerators [#inf]_
or CPUs as a percent of the
:ref:`total active L2 cycles <total-active-l2-cycles>`.
- Percent
* - Write - HBM Stall
- The number of cycles the L2-Fabric interface was stalled on write or
atomic requests to accelerator's local HBM as a percent of the
:ref:`total active L2 cycles <total-active-l2-cycles>`.
- Percent
* - Write - Credit Starvation
- The number of cycles the L2-Fabric interface was stalled on write or
atomic requests to any memory location because too many write/atomic
requests were currently in flight, as a percent of the
:ref:`total active L2 cycles <total-active-l2-cycles>`.
- Percent
.. warning::
On current CDNA accelerators and GCN GPUs, these L2↔Fabric stalls can be undercounted in some circumstances.
.. rubric:: Footnotes
.. [#inf] In addition to being used for on-accelerator data-traffic, AMD
`Infinity Fabric <https://www.amd.com/en/technologies/infinity-architecture>`_
technology can be used to connect multiple accelerators to achieve advanced
peer-to-peer connectivity and enhanced bandwidths over traditional PCIe
connections. Some AMD Instinct MI-series accelerators like the MI250X
`feature coherent CPU↔accelerator connections built using AMD Infinity Fabric <https://www.amd.com/system/files/documents/amd-cdna2-white-paper.pdf>`_.
.. rubric:: Disclaimer
PCIe® is a registered trademark of PCI-SIG Corporation.
+183
View File
@@ -0,0 +1,183 @@
.. meta::
:description: Omniperf performance model: Local data share (LDS)
:keywords: Omniperf, ROCm, profiler, tool, Instinct, accelerator, local, data, share, LDS
**********************
Local data share (LDS)
**********************
.. _lds-sol:
LDS Speed-of-Light
==================
.. warning::
The theoretical maximum throughput for some metrics in this section are
currently computed with the maximum achievable clock frequency, as reported
by ``rocminfo``, for an accelerator. This may not be realistic for all
workloads.
The :ref:`LDS <desc-lds>` speed-of-light chart shows a number of key metrics for
the LDS as a comparison with the peak achievable values of those metrics.
.. list-table::
:header-rows: 1
* - Metric
- Description
- Unit
* - Utilization
- Indicates what percent of the kernel's duration the :ref:`LDS <desc-lds>`
was actively executing instructions (including, but not limited to, load,
store, atomic and HIP's ``__shfl`` operations). Calculated as the ratio
of the total number of cycles LDS was active over the
:ref:`total CU cycles <total-cu-cycles>`.
- Percent
* - Access Rate
- Indicates the percentage of SIMDs in the :ref:`VALU <desc-valu>` [#lds-workload]_
actively issuing LDS instructions, averaged over the lifetime of the
kernel. Calculated as the ratio of the total number of cycles spent by
the :ref:`scheduler <desc-scheduler>` issuing :ref:`LDS <desc-lds>`
instructions over the
:ref:`total CU cycles <total-cu-cycles>`.
- Percent
* - Theoretical Bandwidth (% of Peak)
- Indicates the maximum amount of bytes that *could* have been loaded from,
stored to, or atomically updated in the LDS in this kernel, as a percent
of the peak LDS bandwidth achievable. See the
:ref:`LDS bandwidth example <lds-bandwidth>` for more detail.
- Percent
* - Bank Conflict Rate
- Indicates the percentage of active LDS cycles that were spent servicing
bank conflicts. Calculated as the ratio of LDS cycles spent servicing
bank conflicts over the number of LDS cycles that would have been
required to move the same amount of data in an uncontended access. [#lds-bank-conflict]_
- Percent
.. rubric:: Footnotes
.. [#lds-workload] Here we assume the typical case where the workload evenly distributes
LDS operations over all SIMDs in a CU (that is, waves on different SIMDs are
executing similar code). For highly unbalanced workloads, where e.g., one
SIMD pair in the CU does not issue LDS instructions at all, this metric is
better interpreted as the percentage of SIMDs issuing LDS instructions on
:ref:`SIMD pairs <desc-lds>` that are actively using the LDS, averaged over
the lifetime of the kernel.
.. [#lds-bank-conflict] The maximum value of the bank conflict rate is less than 100%
(specifically: 96.875%), as the first cycle in the
:ref:`LDS scheduler <desc-lds>` is never considered contended.
.. _lds-stats:
Statistics
==========
The LDS statistics panel gives a more detailed view of the hardware:
.. list-table::
:header-rows: 1
* - Metric
- Description
- Unit
* - LDS Instructions
- The total number of LDS instructions (including, but not limited to,
read/write/atomics and HIP's ``__shfl`` instructions) executed per
:ref:`normalization unit <normalization-units>`.
- Instructions per :ref:`normalization unit <normalization-units>`
* - Theoretical Bandwidth
- Indicates the maximum amount of bytes that could have been loaded from,
stored to, or atomically updated in the LDS per
:ref:`normalization unit <normalization-units>`. Does *not* take into
account the execution mask of the wavefront when the instruction was
executed. See the
:ref:`LDS bandwidth example <lds-bandwidth>` for more detail.
- Bytes per :ref:`normalization unit <normalization-units>`
* - LDS Latency
- The average number of round-trip cycles (i.e., from issue to data-return
/ acknowledgment) required for an LDS instruction to complete.
- Cycles
* - Bank Conflicts/Access
- The ratio of the number of cycles spent in the
:ref:`LDS scheduler <desc-lds>` due to bank conflicts (as determined by
the conflict resolution hardware) to the base number of cycles that would
be spent in the LDS scheduler in a completely uncontended case. This is
the unnormalized form of the Bank Conflict Rate.
- Conflicts/Access
* - Index Accesses
- The total number of cycles spent in the :ref:`LDS scheduler <desc-lds>`
over all operations per :ref:`normalization unit <normalization-units>`.
- Cycles per :ref:`normalization unit <normalization-units>`
* - Atomic Return Cycles
- The total number of cycles spent on LDS atomics with return per
:ref:`normalization unit <normalization-units>`.
- Cycles per :ref:`normalization unit <normalization-units>`
* - Bank Conflicts
- The total number of cycles spent in the :ref:`LDS scheduler <desc-lds>`
due to bank conflicts (as determined by the conflict resolution hardware)
per :ref:`normalization unit <normalization-units>`.
- Cycles per :ref:`normalization unit <normalization-units>`
* - Address Conflicts
- The total number of cycles spent in the :ref:`LDS scheduler <desc-lds>`
due to address conflicts (as determined by the conflict resolution
hardware) per :ref:`normalization unit <normalization-units>`.
- Cycles per :ref:`normalization unit <normalization-units>`
* - Unaligned Stall
- The total number of cycles spent in the :ref:`LDS scheduler <desc-lds>`
due to stalls from non-dword aligned addresses per
:ref:`normalization unit <normalization-units>`.
- Cycles per :ref:`normalization unit <normalization-units>`
* - Memory Violations
- The total number of out-of-bounds accesses made to the LDS, per
:ref:`normalization unit <normalization-units>`. This is unused and
expected to be zero in most configurations for modern CDNA™ accelerators.
- Accesses per :ref:`normalization unit <normalization-units>`
+49
View File
@@ -0,0 +1,49 @@
.. meta::
:description: Omniperf performance model
:keywords: Omniperf, ROCm, performance, model, profiler, tool, Instinct,
accelerator, AMD
*****************
Performance model
*****************
Omniperf makes available an extensive list of metrics to better understand
achieved application performance on AMD Instinct™ MI-series accelerators
including Graphics Core Next™ (GCN) GPUs like the AMD Instinct MI50, CDNA™
accelerators like the MI100, and CDNA2 accelerators such as the MI250X, MI250,
and MI210.
To best use profiling data, it's important to understand the role of various
hardware blocks of AMD Instinct accelerators. This section describes each
hardware block on the accelerator as interacted with by a software developer to
give a deeper understanding of the metrics reported by profiling data. Refer to
:doc:`/tutorial/profiling-by-example` for more practical examples and details on how
to use Omniperf to optimize your code.
.. _mixxx-note:
.. note::
In this chapter, **MI2XX** refers to any of the CDNA2 architecture-based AMD
Instinct MI250X, MI250, and MI210 accelerators interchangeably in cases
where the exact product at hand is not relevant.
For a comparison of AMD Instinct accelerator specifications, refer to
:doc:`Hardware specifications <rocm:reference/gpu-arch-specs>`. For product
details, see the :prod-page:`MI250X <mi200/mi250x>`,
:prod-page:`MI250 <mi200/mi250>`, and :prod-page:`MI210 <mi200/mi210>`
product pages.
In this chapter, the AMD Instinct performance model used by Omniperf is divided into a handful of
key hardware blocks, each detailed in the following sections:
* :doc:`compute-unit`
* :doc:`l2-cache`
* :doc:`shader-engine`
* :doc:`command-processor`
* :doc:`system-speed-of-light`
+299
View File
@@ -0,0 +1,299 @@
.. meta::
:description: Omniperf performance model: Shader engine (SE)
:keywords: Omniperf, ROCm, profiler, tool, Instinct, accelerator, pipeline, VALU, SALU, VMEM, SMEM, LDS, branch,
scheduler, MFMA, AGPRs
*********************
Pipeline descriptions
*********************
This section details the various execution pipelines of the
:doc:`compute unit <compute-unit>`.
.. _desc-valu:
.. _desc-vmem:
Vector arithmetic logic unit (VALU)
-----------------------------------
The vector arithmetic logic unit (VALU) executes vector instructions
over an entire wavefront, each :ref:`work-item <desc-work-item>` (or,
vector-lane) potentially operating on distinct data. The VALU of a CDNA™
accelerator or GCN™ GPU typically consists of:
* Four 16-wide SIMD processors (see :hip-training-pdf:`24` for more details).
* Four 64 or 128 KiB VGPR files (yielding a total of 256-512 KiB total
per CU), see :ref:`AGPRs <desc-agprs>` for more detail.
* An instruction buffer (per-SIMD) that contains execution slots for up
to 8 wavefronts (for 32 total wavefront slots on each CU).
* A vector memory (VMEM) unit which transfers data between VGPRs and
memory; each work-item supplies its own memory address and supplies
or receives unique data.
* CDNA accelerators, such as the MI100 and :ref:`MI2XX <mixxx-note>`, contain
additional
:amd-lab-note:`Matrix Fused Multiply-Add (MFMA) <amd-lab-notes-matrix-cores-readme>`
units.
To support branching and conditionals, each wavefront in the VALU
has a distinct execution mask which determines which work-items in the
wavefront are active for the currently executing instruction. When
executing a VALU instruction, inactive work-items (according to the
current execution mask of the wavefront) do not execute the instruction
and are treated as no-ops.
.. note::
On GCN GPUs and the CDNA MI100 accelerator, there are slots for up to 10
wavefronts in the instruction buffer, but generally occupancy is limited by
other factors to 32 waves per :doc:`compute unit <compute-unit>`.
On the CDNA2 :ref:`MI2XX <mixxx-note>` series accelerators, there are only 8
waveslots per-SIMD.
.. _desc-salu:
.. _desc-smem:
Scalar arithmetic logic unit (SALU)
-----------------------------------
The scalar arithmetic logic unit (SALU) executes instructions that are
shared between all work-items in a wavefront. This includes control flow
such as if/else conditionals, branches and looping pointer arithmetic, loading
common values, and more.
The SALU consists of:
* A scalar processor capable of various arithmetic, conditional, and
comparison (etc.) operations. See
:mi200-isa-pdf:`Chapter 5. Scalar ALU Operations <35>`
of the CDNA2 Instruction Set Architecture (ISA) Reference Guide for more
detail.
* A 12.5 KiB Scalar General Purpose Register (SGPR) file
* A scalar memory (SMEM) unit which transfers data between SGPRs and
memory
Data loaded by the SMEM can be cached in the :ref:`scalar L1 data cache <desc-sl1d>`,
and is typically only used for read-only, uniform accesses such as kernel
arguments, or HIP’s ``__constant__`` memory.
.. _desc-lds:
Local data share (LDS)
----------------------
The local data share (LDS, a.k.a., "shared memory") is fast on-CU scratchpad
that can be explicitly managed by software to effectively share data and to
coordinate between wavefronts in a workgroup.
.. figure:: ../data/performance-model/lds.*
:align: center
:alt: Performance model of the local data share (LDS) on AMD Instinct
accelerators
:width: 800
Performance model of the local data share (LDS) on AMD Instinct MI-series
accelerators.
Above is Omniperf's performance model of the LDS on CDNA accelerators (adapted
from :mantor-gcn-pdf:`20`). The SIMDs in the :ref:`VALU <desc-valu>` are
connected to the LDS in pairs (see above). Only one SIMD per pair may issue an
LDS instruction at a time, but both pairs may issue concurrently.
On CDNA accelerators, the LDS contains 32 banks and each bank is 4B wide.
The LDS is designed such that each bank can be read from, written to, or
atomically updated every cycle, for a total throughput of 128B/clock
(:gcn-crash-course:`40`).
On each of the two ports to the SIMDs, 64B can be sent in each direction per
cycle. So, a single wavefront, coming from one of the 2 SIMDs in a pair, can
only get back 64B/cycle (16 lanes per cycle). The input port is shared between
data and address and this can affect achieved bandwidth for different data
sizes. For example, a 64-wide store where each lane is sending a 4B value takes
8 cycles (50% peak bandwidth) while a 64-wide store where each lane is sending
a 16B value takes 20 cycles (80% peak bandwidth).
In addition, the LDS contains conflict-resolution hardware to detect and handle
bank conflicts. A bank conflict occurs when two (or more)
:ref:`work-items <desc-work-item>` in a :ref:`wavefront <desc-wavefront>` want
to read, write, or atomically update different addresses that map to the same
bank in the same cycle. In this case, the conflict detection hardware will
determine a new schedule such that the access is split into multiple cycles with
no conflicts in any single cycle.
When multiple work-items want to read from the same address within a bank, the
result can be efficiently broadcasted (:gcn-crash-course:`41`). Multiple
work-items writing to the same address within a bank typically results undefined
behavior in HIP and other high-level languages, as the LDS will write the value from the
last work-item as determined by the hardware scheduler (:gcn-crash-course:`41`).
This behavior may be useful in the very specific case of storing a uniform
value.
Relatedly, an address conflict is defined as occurring when two (or more)
work-items in a wavefront want to atomically update the same address on the same
cycle. As in a bank-conflict, this may cause additional cycles of work for the
LDS operation to complete.
.. _desc-branch:
Branch
------
The branch unit is responsible for executing jumps and branches to execute
control flow operations.
Note that Branch operations are not used for execution mask updates, but only
for “whole wavefront” control-flow changes.
.. _desc-scheduler:
Scheduler
---------
The scheduler is responsible for arbitration and issue of instructions for all
the wavefronts currently executing on the :doc:`CU <compute-unit>`. On every
clock cycle, the scheduler:
* Considers waves from one of the SIMD units for execution, selected in a
round-robin fashion between the SIMDs in the compute unit
* Issues up to one instruction per wavefront on the selected SIMD
* Issues up to one instruction per each of the instruction categories among the waves on the selected SIMD:
* :ref:`VALU <desc-valu>`
* :ref:`VMEM <desc-vmem>` operations
* :ref:`SALU <desc-salu>` / SMEM operations
* :ref:`LDS <desc-lds>`
* :ref:`Branch <desc-branch>` operations
This gives a maximum of five issued Instructions Per Cycle (IPC), per-SIMD,
per-CU (:hip-training-pdf:`Introduction to AMD GPU Programming with HIP <>`,
:gcn-crash-course:`The AMD GCN Architecture - A Crash Course <>`). On CDNA
accelerators with :ref:`MFMA <desc-mfma>` instructions, these are issued via the
:ref:`VALU <desc-valu>`. Some of them will execute on a separate functional unit
and typically allow other :ref:`VALU <desc-valu>` operations to execute in their
shadow (see the :ref:`MFMA <desc-mfma>` section for more detail).
.. note::
The IPC model used by Omniperf omits the following two complications for
clarity. First, CDNA accelerators contain other execution units on the CU
that are unused for compute applications. Second, so-called "internal"
instructions (see :gcn-crash-course:`29`) are not issued to a functional
unit, and can technically cause the maximum IPC to *exceed* 5 instructions
per-cycle in special (largely unrealistic) cases. The latter issue is
discussed in more detail in the
:ref:`'internal' IPC <ipc-internal-instructions>` example.
.. _desc-mfma:
Matrix fused multiply-add (MFMA)
--------------------------------
CDNA accelerators, such as the MI100 and :ref:`MI2XX <mixxx-note>`, contain
specialized hardware to accelerate matrix-matrix multiplications, also
known as Matrix Fused Multiply-Add (MFMA) operations. The exact
operation types and supported formats may vary by accelerator. Refer to the
:amd-lab-note:`AMD matrix cores <amd-lab-notes-matrix-cores-readme>`
blog post on GPUOpen for a general discussion of these hardware units.
In addition, to explore the available MFMA instructions in-depth on
various AMD accelerators (including the CDNA line), we recommend the
`AMD Matrix Instruction Calculator <https://github.com/ROCm/amd_matrix_instruction_calculator>`_:
.. code-block:: shell
:caption: Partial snapshot of the AMD Matrix Instruction Calculator Tool
$ ./matrix_calculator.py architecture cdna2 instruction v_mfma_f32_4x4x1f32 detail-instruction
Architecture: CDNA2
Instruction: V_MFMA_F32_4X4X1F32
Encoding: VOP3P-MAI
VOP3P Opcode: 0x42
VOP3P-MAI Opcode: 0x2
Matrix Dimensions:
M: 4
N: 4
K: 1
blocks: 16
Execution statistics:
FLOPs: 512
Execution cycles: 8
FLOPs/CU/cycle: 256
Can co-execute with VALU: True
VALU co-execution cycles possible: 4
Register usage:
GPRs required for A: 1
GPRs required for B: 1
GPRs required for C: 4
GPRs required for D: 4
GPR alignment requirement: 8 bytes
For the purposes of Omniperf, the MFMA unit is typically treated as a separate
pipeline from the :ref:`VALU <desc-valu>`, as other VALU instructions (along
with other execution pipelines such as the :ref:`SALU <desc-salu>`) typically can be
issued during a portion of the total duration of an MFMA operation.
.. note::
The exact details of VALU and MFMA operation co-execution vary by
instruction, and can be explored in more detail via the following fields in
the
`AMD Matrix Instruction Calculator's detailed instruction information <https://github.com/ROCm/amd_matrix_instruction_calculator#example-of-querying-instruction-information>`_:
* ``Can co-execute with VALU``
* ``VALU co-execution cycles possible``
Non-pipeline resources
----------------------
In this section, we describe a few resources that are not standalone
pipelines but are important for understanding performance optimization
on CDNA accelerators.
.. _desc-barrier:
Barrier
^^^^^^^
Barriers are resources on the compute-unit of a CDNA accelerator that
are used to implement synchronization primitives (for example, HIP’s
``__syncthreads``). Barriers are allocated to any workgroup that
consists of more than a single wavefront.
.. _desc-agprs:
Accumulation vector general-purpose registers (AGPRs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Accumulation vector general-purpose registers, or AGPRs, are special
resources that are accessible to a subset of instructions focused on
:ref:`MFMA <desc-mfma>` operations. These registers allow the MFMA
unit to access more than the normal maximum of 256 architected
:ref:`vector general-purpose registers (VGPRs) <desc-valu>` by having up to 256
in the architected space and up to 256 in the accumulation space.
Traditional VALU instructions can only use VGPRs in the architected
space, and data can be moved to/from VGPRs↔AGPRs using specialized
instructions (``v_accvgpr_*``). These data movement instructions may be
used by the compiler to implement lower-cost register-spill/fills on
architectures with AGPRs.
AGPRs are not available on all AMD Instinct™ accelerators. GCN GPUs,
such as the AMD Instinct MI50 had a 256 KiB VGPR file. The AMD
Instinct MI100 (CDNA) has a 2x256 KiB register file, where one half
is available as general-purpose VGPRs, and the other half is for matrix
math accumulation VGPRs (AGPRs). The AMD Instinct :ref:`MI2XX <mixxx-note>`
(CDNA2) has a 512 KiB VGPR file per CU, where each wave can dynamically request
up to 256 KiB of VGPRs and an additional 256 KiB of AGPRs. For more information,
refer to `this comment <https://github.com/ROCm/ROCm/issues/1689#issuecomment-1553751913>`_.
+909
View File
@@ -0,0 +1,909 @@
.. meta::
:description: Omniperf performance model: Pipeline metrics
:keywords: Omniperf, ROCm, profiler, tool, Instinct, accelerator, pipeline, wavefront, metrics, launch, runtime
VALU, MFMA, instruction mix, FLOPs, arithmetic, operations
****************
Pipeline metrics
****************
In this section, we describe the metrics available in Omniperf to analyze the
pipelines discussed in the :doc:`pipeline-descriptions`.
.. _wavefront:
Wavefront
=========
.. _wavefront-launch-stats:
Wavefront launch stats
----------------------
The wavefront launch stats panel gives general information about the
kernel launch:
.. list-table::
:header-rows: 1
:widths: 20 65 15
* - Metric
- Description
- Unit
* - Grid Size
- The total number of work-items (or, threads) launched as a part of
the kernel dispatch. In HIP, this is equivalent to the total grid size
multiplied by the total workgroup (or, block) size.
- :ref:`Work-items <desc-work-item>`
* - Workgroup Size
- The total number of work-items (or, threads) in each workgroup
(or, block) launched as part of the kernel dispatch. In HIP, this is
equivalent to the total block size.
- :ref:`Work-items <desc-work-item>`
* - Total Wavefronts
- The total number of wavefronts launched as part of the kernel dispatch.
On AMD Instinct™ CDNA™ accelerators and GCN™ GPUs, the wavefront size is
always 64 work-items. Thus, the total number of wavefronts should be
equivalent to the ceiling of grid size divided by 64.
- :ref:`Wavefronts <desc-wavefront>`
* - Saved Wavefronts
- The total number of wavefronts saved at a context-save. See
`cwsr_enable <https://docs.kernel.org/gpu/amdgpu/module-parameters.html?highlight=cwsr>`_.
- :ref:`Wavefronts <desc-wavefront>`
* - Restored Wavefronts
- The total number of wavefronts restored from a context-save. See
`cwsr_enable <https://docs.kernel.org/gpu/amdgpu/module-parameters.html?highlight=cwsr>`_.
- :ref:`Wavefronts <desc-wavefront>`
* - VGPRs
- The number of architected vector general-purpose registers allocated for
the kernel, see :ref:`VALU <desc-valu>`. Note: this may not exactly
match the number of VGPRs requested by the compiler due to allocation
granularity.
- :ref:`VGPRs <desc-valu>`
* - AGPRs
- The number of accumulation vector general-purpose registers allocated for
the kernel, see :ref:`AGPRs <desc-agprs>`. Note: this may not exactly
match the number of AGPRs requested by the compiler due to allocation
granularity.
- :ref:`AGPRs <desc-agprs>`
* - SGPRs
- The number of scalar general-purpose registers allocated for the kernel,
see :ref:`SALU <desc-salu>`. Note: this may not exactly match the number
of SGPRs requested by the compiler due to allocation granularity.
- :ref:`SGPRs <desc-salu>`
* - LDS Allocation
- The number of bytes of :doc:`LDS <local-data-share>` memory (or, shared
memory) allocated for this kernel. Note: This may also be larger than
what was requested at compile time due to both allocation granularity and
dynamic per-dispatch LDS allocations.
- Bytes per :ref:`workgroup <desc-workgroup>`
* - Scratch Allocation
- The number of bytes of :ref:`scratch memory <memory-spaces>` requested
per work-item for this kernel. Scratch memory is used for stack memory
on the accelerator, as well as for register spills and restores.
- Bytes per :ref:`work-item <desc-work-item>`
.. _wavefront-runtime-stats:
Wavefront runtime stats
-----------------------
The wavefront runtime statistics gives a high-level overview of the
execution of wavefronts in a kernel:
.. list-table::
:header-rows: 1
:widths: 18 65 17
* - Metric
- Description
- Unit
* - :ref:`Kernel time <kernel-time>`
- The total duration of the executed kernel. Note: this should not be
directly compared to the wavefront cycles / timings below.
- Nanoseconds
* - :ref:`Kernel cycles <kernel-cycles>`
- The total duration of the executed kernel in cycles. Note: this should
not be directly compared to the wavefront cycles / timings below.
- Cycles
* - Instructions per wavefront
- The average number of instructions (of all types) executed per wavefront.
This is averaged over all wavefronts in a kernel dispatch.
- Instructions / wavefront
* - Wave cycles
- The number of cycles a wavefront in the kernel dispatch spent resident on
a compute unit per :ref:`normalization unit <normalization-units>`. This
is averaged over all wavefronts in a kernel dispatch. Note: this should
not be directly compared to the kernel cycles above.
- Cycles per :ref:`normalization unit <normalization-units>`
* - Dependency wait cycles
- The number of cycles a wavefront in the kernel dispatch stalled waiting
on memory of any kind (e.g., instruction fetch, vector or scalar memory,
etc.) per :ref:`normalization unit <normalization-units>`. This counter
is incremented at every cycle by *all* wavefronts on a CU stalled at a
memory operation. As such, it is most useful to get a sense of how waves
were spending their time, rather than identification of a precise limiter
because another wave could be actively executing while a wave is stalled.
The sum of this metric, Issue Wait Cycles and Active Cycles should be
equal to the total Wave Cycles metric.
- Cycles per :ref:`normalization unit <normalization-units>`
* - Issue Wait Cycles
- The number of cycles a wavefront in the kernel dispatch was unable to
issue an instruction for any reason (e.g., execution pipe back-pressure,
arbitration loss, etc.) per
:ref:`normalization unit <normalization-units>`. This counter is
incremented at every cycle by *all* wavefronts on a CU unable to issue an
instruction. As such, it is most useful to get a sense of how waves were
spending their time, rather than identification of a precise limiter
because another wave could be actively executing while a wave is issue
stalled. The sum of this metric, Dependency Wait Cycles and Active
Cycles should be equal to the total Wave Cycles metric.
- Cycles per :ref:`normalization unit <normalization-units>`
* - Active Cycles
- The average number of cycles a wavefront in the kernel dispatch was
actively executing instructions per
:ref:`normalization unit <normalization-units>`. This measurement is made
on a per-wavefront basis, and may include cycles that another wavefront
spent actively executing (on another execution unit, for example) or was
stalled. As such, it is most useful to get a sense of how waves were
spending their time, rather than identification of a precise limiter. The
sum of this metric, Issue Wait Cycles and Active Wait Cycles should be
equal to the total Wave Cycles metric.
- Cycles per :ref:`normalization unit <normalization-units>`
* - Wavefront Occupancy
- The time-averaged number of wavefronts resident on the accelerator over
the lifetime of the kernel. Note: this metric may be inaccurate for
short-running kernels (less than 1ms).
- :ref:`Wavefronts <desc-wavefront>`
.. note::
As mentioned earlier, the measurement of kernel cycles and time typically
cannot be directly compared to, for example, wave cycles. This is due to two factors:
first, the kernel cycles/timings are measured using a counter that is
impacted by scheduling overhead, this is particularly noticeable for
"short-running" kernels (less than 1ms) where scheduling overhead forms a
significant portion of the overall kernel runtime. Secondly, the wave cycles
metric is incremented per-wavefront scheduled to a SIMD every cycle whereas
the kernel cycles counter is incremented only once per-cycle when *any*
wavefront is scheduled.
.. _instruction-mix:
Instruction mix
===============
The instruction mix panel shows a breakdown of the various types of instructions
executed by the user’s kernel, and which pipelines on the
:doc:`CU <compute-unit>` they were executed on. In addition, Omniperf reports
further information about the breakdown of operation types for the
:ref:`VALU <desc-valu>`, vector-memory, and :ref:`MFMA <desc-mfma>`
instructions.
.. note::
All metrics in this section count *instructions issued*, and *not* the total
number of operations executed. The values reported by these metrics will not
change regardless of the execution mask of the wavefront. Note that even if
the execution mask is identically zero (meaning that *no lanes are active*)
the instruction will still be counted, as CDNA accelerators still consider
these instructions *issued*. See
:mi200-isa-pdf:`EXECute Mask, section 3.3 of the CDNA2 ISA guide<19>` for
examples and further details.
Overall instruction mix
-----------------------
This panel shows the total number of each type of instruction issued to
the :doc:`various compute pipelines </conceptual/pipeline-descriptions>` on the
:doc:`CU </conceptual/compute-unit>`. These are:
.. list-table::
:header-rows: 1
* - Metric
- Description
- Unit
* - :ref:`VALU <desc-valu>` instructions
- The total number of vector arithmetic logic unit (VALU) operations
issued. These are the workhorses of the
:doc:`compute unit <compute-unit>`, and are used to execute a wide range of
instruction types including floating point operations, non-uniform
address calculations, transcendental operations, integer operations,
shifts, conditional evaluation, etc.
- Instructions
* - VMEM instructions
- The total number of vector memory operations issued. These include most
loads, stores and atomic operations and all accesses to
:ref:`generic, global, private and texture <memory-spaces>` memory.
- Instructions
* - :doc:`LDS <local-data-share>` instructions
- The total number of LDS (also known as shared memory) operations issued.
These include loads, stores, atomics, and HIP's ``__shfl`` operations.
- Instructions
* - :ref:`MFMA <desc-mfma>` instructions
- The total number of matrix fused multiply-add instructions issued.
- Instructions
* - :ref:`SALU <desc-salu>` instructions
- The total number of scalar arithmetic logic unit (SALU) operations
issued. Typically these are used for address calculations, literal
constants, and other operations that are *provably* uniform across a
wavefront. Although scalar memory (SMEM) operations are issued by the
SALU, they are counted separately in this section.
- Instructions
* - SMEM instructions
- The total number of scalar memory (SMEM) operations issued. These are
typically used for loading kernel arguments, base-pointers and loads
from HIP's ``__constant__`` memory.
- Instructions
* - :ref:`Branch <desc-branch>` instructions
- The total number of branch operations issued. These typically consist of
jump or branch operations and are used to implement control flow.
- Instructions
.. note::
Note, as mentioned in the :ref:`desc-branch` section: branch
operations are not used for execution mask updates, but only for "whole
wavefront" control flow changes.
.. _valu-arith-instruction-mix:
VALU arithmetic instruction mix
-------------------------------
.. warning::
Not all metrics in this section (for instance, the floating-point instruction
breakdowns) are available on CDNA accelerators older than the
:ref:`MI2XX <mixxx-note>` series.
This panel details the various types of vector instructions that were
issued to the :ref:`VALU <desc-valu>`. The metrics in this section do *not*
include :ref:`MFMA <desc-mfma>` instructions using the same precision; for
instance, the “F16-ADD” metric does not include any 16-bit floating point
additions executed as part of an MFMA instruction using the same precision.
.. list-table::
:header-rows: 1
:widths: 15 65 20
* - Metric
- Description
- Unit
* - INT32
- The total number of instructions operating on 32-bit integer operands
issued to the VALU per :ref:`normalization unit <normalization-units>`.
- Instructions per :ref:`normalization unit <normalization-units>`
* - INT64
- The total number of instructions operating on 64-bit integer operands
issued to the VALU per :ref:`normalization unit <normalization-units>`.
- Instructions per :ref:`normalization unit <normalization-units>`
* - F16-ADD
- The total number of addition instructions operating on 16-bit
floating-point operands issued to the VALU per
:ref:`normalization unit <normalization-units>`.
- Instructions per :ref:`normalization unit <normalization-units>`
* - F16-MUL
- The total number of multiplication instructions operating on 16-bit
floating-point operands issued to the VALU per
:ref:`normalization unit <normalization-units>`.
- Instructions per :ref:`normalization unit <normalization-units>`
* - F16-FMA
- The total number of fused multiply-add instructions operating on 16-bit
floating-point operands issued to the VALU per
:ref:`normalization unit <normalization-units>`.
- Instructions per :ref:`normalization unit <normalization-units>`
* - F16-TRANS
- The total number of transcendental instructions (e.g., `sqrt`) operating
on 16-bit floating-point operands issued to the VALU per
:ref:`normalization unit <normalization-units>`.
- Instructions per :ref:`normalization unit <normalization-units>`
* - F32-ADD
- The total number of addition instructions operating on 32-bit
floating-point operands issued to the VALU per
:ref:`normalization unit <normalization-units>`.
- Instructions per :ref:`normalization unit <normalization-units>`
* - F32-MUL
- The total number of multiplication instructions operating on 32-bit
floating-point operands issued to the VALU per
:ref:`normalization unit <normalization-units>`.
- Instructions per :ref:`normalization unit <normalization-units>`
* - F32-FMA
- The total number of fused multiply-add instructions operating on 32-bit
floating-point operands issued to the VALU per
:ref:`normalization unit <normalization-units>`.
- Instructions per :ref:`normalization unit <normalization-units>`
* - F32-TRANS
- The total number of transcendental instructions (such as ``sqrt``)
operating on 32-bit floating-point operands issued to the VALU per
:ref:`normalization unit <normalization-units>`.
- Instructions per :ref:`normalization unit <normalization-units>`
* - F64-ADD
- The total number of addition instructions operating on 64-bit
floating-point operands issued to the VALU per
:ref:`normalization unit <normalization-units>`.
- Instructions per :ref:`normalization unit <normalization-units>`
* - F64-MUL
- The total number of multiplication instructions operating on 64-bit
floating-point operands issued to the VALU per
:ref:`normalization unit <normalization-units>`.
- Instructions per :ref:`normalization unit <normalization-units>`
* - F64-FMA
- The total number of fused multiply-add instructions operating on 64-bit
floating-point operands issued to the VALU per
:ref:`normalization unit <normalization-units>`.
- Instructions per :ref:`normalization unit <normalization-units>`
* - F64-TRANS
- The total number of transcendental instructions (such as `sqrt`)
operating on 64-bit floating-point operands issued to the VALU per
:ref:`normalization unit <normalization-units>`.
- Instructions per :ref:`normalization unit <normalization-units>`
* - Conversion
- The total number of type conversion instructions (such as converting data
to or from F32↔F64) issued to the VALU per
:ref:`normalization unit <normalization-units>`.
- Instructions per :ref:`normalization unit <normalization-units>`
For an example of these counters in action, refer to
:ref:`valu-arith-instruction-mix-ex`.
.. _vmem-instruction-mix:
VMEM instruction mix
--------------------
This section breaks down the types of vector memory (VMEM) instructions
that were issued. Refer to the
:ref:`Instruction Counts metrics section <ta-instruction-counts>` under address
processor front end of the vL1D cache for descriptions of these VMEM
instructions.
.. _mfma-instruction-mix:
MFMA instruction mix
--------------------
.. warning::
The metrics in this section are only available on CDNA2
(:ref:`MI2XX <mixxx-note>`) accelerators and newer.
This section details the types of Matrix Fused Multiply-Add
(:ref:`MFMA <desc-mfma>`) instructions that were issued. Note that
MFMA instructions are classified by the type of input data they operate on, and
*not* the data type the result is accumulated to.
.. list-table::
:header-rows: 1
:widths: 25 60 17
* - Metric
- Description
- Unit
* - MFMA-I8 Instructions
- The total number of 8-bit integer :ref:`MFMA <desc-mfma>` instructions
issued per :ref:`normalization unit <normalization-units>`.
- Instructions per :ref:`normalization unit <normalization-units>`
* - MFMA-F16 Instructions
- The total number of 16-bit floating point :ref:`MFMA <desc-mfma>`
instructions issued per :ref:`normalization unit <normalization-units>`.
- Instructions per :ref:`normalization unit <normalization-units>`
* - MFMA-BF16 Instructions
- The total number of 16-bit brain floating point :ref:`MFMA <desc-mfma>`
instructions issued per :ref:`normalization unit <normalization-units>`.
- Instructions per :ref:`normalization unit <normalization-units>`
* - MFMA-F32 Instructions
- The total number of 32-bit floating-point :ref:`MFMA <desc-mfma>`
instructions issued per :ref:`normalization unit <normalization-units>`.
- Instructions per :ref:`normalization unit <normalization-units>`
* - MFMA-F64 Instructions
- The total number of 64-bit floating-point :ref:`MFMA <desc-mfma>`
instructions issued per :ref:`normalization unit <normalization-units>`.
- Instructions per :ref:`normalization unit <normalization-units>`
Compute pipeline
================
.. _metrics-flop-count:
FLOP counting conventions
-------------------------
Omniperf’s conventions for VALU FLOP counting are as follows:
* Addition or multiplication: 1 operation
* Transcendentals: 1 operation
* Fused multiply-add (FMA): 2 operations
Integer operations (IOPs) do not use this convention. They are counted
as a single operation regardless of the instruction type.
.. note::
Packed operations which operate on multiple operands in the same instruction
are counted identically to the underlying instruction type. For example, the
``v_pk_add_f32`` instruction on :ref:`MI2XX <mixxx-note>`, which performs an
add operation on two pairs of aligned 32-bit floating-point operands is
counted only as a single addition -- that is, 1 operation.
As discussed in the :ref:`instruction-mix` section, the FLOP/IOP
metrics in this section do not take into account the execution mask of
the operation, and will report the same value even if the execution mask
is identically zero.
For example, a FMA instruction operating on 32-bit floating-point
operands (such as ``v_fma_f32`` on a :ref:`MI2XX <mixxx-note>` accelerator)
would be counted as 128 total FLOPs: 2 operations (due to the
instruction type) multiplied by 64 operations (because the wavefront is
composed of 64 work-items).
.. _compute-speed-of-light:
Compute Speed-of-Light
----------------------
.. warning::
The theoretical maximum throughput for some metrics in this section are
currently computed with the maximum achievable clock frequency, as reported
by ``rocminfo``, for an accelerator. This may not be realistic for all
workloads.
This section reports the number of floating-point and integer operations
executed on the :ref:`VALU <desc-valu>` and :ref:`MFMA <desc-mfma>` units in
various precisions. We note that unlike the
:ref:`VALU instruction mix <valu-arith-instruction-mix>` and
:ref:`MFMA instruction mix <mfma-instruction-mix>` sections, the metrics here
are reported as FLOPs and IOPs, that is, the total number of operations
executed.
.. list-table::
:header-rows: 1
* - Metric
- Description
- Unit
* - VALU FLOPs
- The total floating-point operations executed per second on the
:ref:`VALU <desc-valu>`. This is also presented as a percent of the peak
theoretical FLOPs achievable on the specific accelerator. Note: this does
not include any floating-point operations from :ref:`MFMA <desc-mfma>`
instructions.
- GFLOPs
* - VALU IOPs
- The total integer operations executed per second on the
:ref:`VALU <desc-valu>`. This is also presented as a percent of the peak
theoretical IOPs achievable on the specific accelerator. Note: this does
not include any integer operations from :ref:`MFMA <desc-mfma>`
instructions.
- GIOPs
* - MFMA FLOPs (BF16)
- The total number of 16-bit brain floating point :ref:`MFMA <desc-mfma>`
operations executed per second. Note: this does not include any 16-bit
brain floating point operations from :ref:`VALU <desc-valu>`
instructions. This is also presented as a percent of the peak theoretical
BF16 MFMA operations achievable on the specific accelerator.
- GFLOPs
* - MFMA FLOPs (F16)
- The total number of 16-bit floating point :ref:`MFMA <desc-mfma>`
operations executed per second. Note: this does not include any 16-bit
floating point operations from :ref:`VALU <desc-valu>` instructions. This
is also presented as a percent of the peak theoretical F16 MFMA
operations achievable on the specific accelerator.
- GFLOPs
* - MFMA FLOPs (F32)
- The total number of 32-bit floating point :ref:`MFMA <desc-mfma>`
operations executed per second. Note: this does not include any 32-bit
floating point operations from :ref:`VALU <desc-valu>` instructions. This
is also presented as a percent of the peak theoretical F32 MFMA
operations achievable on the specific accelerator.
- GFLOPs
* - MFMA FLOPs (F64)
- The total number of 64-bit floating point :ref:`MFMA <desc-mfma>`
operations executed per second. Note: this does not include any 64-bit
floating point operations from :ref:`VALU <desc-valu>` instructions. This
is also presented as a percent of the peak theoretical F64 MFMA
operations achievable on the specific accelerator.
- GFLOPs
* - MFMA IOPs (INT8)
- The total number of 8-bit integer :ref:`MFMA <desc-mfma>` operations
executed per second. Note: this does not include any 8-bit integer
operations from :ref:`VALU <desc-valu>` instructions. This is also
presented as a percent of the peak theoretical INT8 MFMA operations
achievable on the specific accelerator.
- GIOPs
.. _pipeline-stats:
Pipeline statistics
-------------------
This section reports a number of key performance characteristics of
various execution units on the :doc:`CU <compute-unit>`. Refer to
:ref:`ipc-example` for a detailed dive into these metrics, and the
:ref:`scheduler <desc-scheduler>` the for a high-level overview of execution
units and instruction issue.
.. list-table::
:header-rows: 1
:widths: 20 65 15
* - Metric
- Description
- Unit
* - IPC
- The ratio of the total number of instructions executed on the
:doc:`CU <compute-unit>` over the
:ref:`total active CU cycles <total-active-cu-cycles>`.
- Instructions per-cycle
* - IPC (Issued)
- The ratio of the total number of
(non-:ref:`internal <ipc-internal-instructions>`) instructions issued over
the number of cycles where the :ref:`scheduler <desc-scheduler>` was
actively working on issuing instructions. Refer to the
:ref:`Issued IPC <issued-ipc>` example for further detail.
- Instructions per-cycle
* - SALU utilization
- Indicates what percent of the kernel's duration the
:ref:`SALU <desc-salu>` was busy executing instructions. Computed as the
ratio of the total number of cycles spent by the
:ref:`scheduler <desc-scheduler>` issuing SALU / :ref:`SMEM <desc-smem>`
instructions over the :ref:`total CU cycles <total-cu-cycles>`.
- Percent
* - VALU utilization
- Indicates what percent of the kernel's duration the
:ref:`VALU <desc-valu>` was busy executing instructions. Does not include
:ref:`VMEM <desc-vmem>` operations. Computed as the ratio of the total
number of cycles spent by the :ref:`scheduler <desc-scheduler>` issuing
VALU instructions over the :ref:`total CU cycles <total-cu-cycles>`.
- Percent
* - VMEM utilization
- Indicates what percent of the kernel's duration the
:ref:`VMEM <desc-vmem>` unit was busy executing instructions, including
both global/generic and spill/scratch operations (see the
:ref:`VMEM instruction count metrics <ta-instruction-counts>` for more
detail). Does not include :ref:`VALU <desc-valu>` operations. Computed
as the ratio of the total number of cycles spent by the
:ref:`scheduler <desc-scheduler>` issuing VMEM instructions over the
:ref:`total CU cycles <total-cu-cycles>`.
- Percent
* - Branch utilization
- Indicates what percent of the kernel's duration the
:ref:`branch <desc-branch>` unit was busy executing instructions.
Computed as the ratio of the total number of cycles spent by the
:ref:`scheduler <desc-scheduler>` issuing branch instructions over the
:ref:`total CU cycles <total-cu-cycles>`.
- Percent
* - VALU active threads
- Indicates the average level of :ref:`divergence <desc-divergence>` within
a wavefront over the lifetime of the kernel. The number of work-items
that were active in a wavefront during execution of each
:ref:`VALU <desc-valu>` instruction, time-averaged over all VALU
instructions run on all wavefronts in the kernel.
- Work-items
* - MFMA utilization
- Indicates what percent of the kernel's duration the
:ref:`MFMA <desc-mfma>` unit was busy executing instructions. Computed as
the ratio of the total number of cycles spent by the
:ref:`MFMA <desc-salu>` was busy over the
:ref:`total CU cycles <total-cu-cycles>`.
- Percent
* - MFMA instruction cycles
- The average duration of :ref:`MFMA <desc-mfma>` instructions in this
kernel in cycles. Computed as the ratio of the total number of cycles the
MFMA unit was busy over the total number of MFMA instructions. Compare
to, for example, the
`AMD Matrix Instruction Calculator <https://github.com/RadeonOpenCompute/amd_matrix_instruction_calculator>`_.
- Cycles per instruction
* - VMEM latency
- The average number of round-trip cycles (that is, from issue to data
return / acknowledgment) required for a VMEM instruction to complete.
- Cycles
* - SMEM latency
- The average number of round-trip cycles (that is, from issue to data
return / acknowledgment) required for a SMEM instruction to complete.
- Cycles
.. note::
The branch utilization reported in this section also includes time spent in
other instruction types (namely: ``s_endpgm``) that are *typically* a very
small percentage of the overall kernel execution. This complication is
omitted for simplicity, but may result in small amounts of branch utilization
(typically less than 1%) for otherwise branch-less kernels.
.. _arithmetic-operations:
Arithmetic operations
---------------------
This section reports the total number of floating-point and integer
operations executed in various precisions. Unlike the
:ref:`compute-speed-of-light` panel, this section reports both
:ref:`VALU <desc-valu>` and :ref:`MFMA <desc-mfma>` operations of the same precision
(e.g., F32) in the same metric. Additionally, this panel lets the user
control how the data is normalized (i.e., control the
:ref:`normalization unit <normalization-units>`), while the speed-of-light panel does
not. For more detail on how operations are counted see the
:ref:`FLOP counting convention <metrics-flop-count>` section.
.. warning::
As discussed in :ref:`instruction-mix`, the metrics in this section do not
take into account the execution mask of the operation, and will report the
same value even if EXEC is identically zero.
.. list-table::
:header-rows: 1
:widths: 18 65 17
* - Metric
- Description
- Unit
* - FLOPs (Total)
- The total number of floating-point operations executed on either the
:ref:`VALU <desc-valu>` or :ref:`MFMA <desc-mfma>` units, per
:ref:`normalization unit <normalization-units>`.
- FLOP per :ref:`normalization unit <normalization-units>`
* - IOPs (Total)
- The total number of integer operations executed on either the
:ref:`VALU <desc-valu>` or :ref:`MFMA <desc-mfma>` units, per
:ref:`normalization unit <normalization-units>`.
- IOP per :ref:`normalization unit <normalization-units>`
* - F16 OPs
- The total number of 16-bit floating-point operations executed on either the
:ref:`VALU <desc-valu>` or :ref:`MFMA <desc-mfma>` units, per
:ref:`normalization unit <normalization-units>`.
- FLOP per :ref:`normalization unit <normalization-units>`
* - BF16 OPs
- The total number of 16-bit brain floating-point operations executed on either the
:ref:`VALU <desc-valu>` or :ref:`MFMA <desc-mfma>` units, per
:ref:`normalization unit <normalization-units>`. Note: on current CDNA
accelerators, the VALU has no native BF16 instructions.
- FLOP per :ref:`normalization unit <normalization-units>`
* - F32 OPs
- The total number of 32-bit floating-point operations executed on either
the :ref:`VALU <desc-valu>` or :ref:`MFMA <desc-mfma>` units, per
:ref:`normalization unit <normalization-units>`.
- FLOP per :ref:`normalization unit <normalization-units>`
* - F64 OPs
- The total number of 64-bit floating-point operations executed on either
the :ref:`VALU <desc-valu>` or :ref:`MFMA <desc-mfma>` units, per
:ref:`normalization unit <normalization-units>`.
- FLOP per :ref:`normalization unit <normalization-units>`
* - INT8 OPs
- The total number of 8-bit integer operations executed on either the
:ref:`VALU <desc-valu>` or :ref:`MFMA <desc-mfma>` units, per
:ref:`normalization unit <normalization-units>`. Note: on current CDNA
accelerators, the VALU has no native INT8 instructions.
- IOPs per :ref:`normalization unit <normalization-units>`
+26
View File
@@ -0,0 +1,26 @@
.. meta::
:description: Omniperf performance model: References
:keywords: Omniperf, ROCm, profiler, tool, Instinct, accelerator, HIP, GCN, LLVM, docs, documentation, training
**********
References
**********
Some sections in :doc:`this chapter </conceptual/performance-model>` cite the
following publicly available documentation.
* :hip-training-pdf:`Introduction to AMD GPU Programming with HIP <>`
* :mi200-isa-pdf:`CDNA2 ISA Reference Guide <>`
* :cdna2-white-paper:`CDNA2 white paper <>`
* :hsa-runtime-pdf:`HSA Runtime Programmer's Reference Manual <>`
* :gcn-crash-course:`The AMD GCN Architecture - A Crash Course (Layla Mah) <>`
* :mantor-gcn-pdf:`AMD Radeon HD7970 with GCN Architecture <>`
* :mantor-vega10-pdf:`AMD Radeon Next Generation GPU Architecture - Vega10 <>`
* :llvm-docs:`LLVM User Guide for AMDGPU Backend <>`
+707
View File
@@ -0,0 +1,707 @@
.. meta::
:description: Omniperf performance model: Shader engine (SE)
:keywords: Omniperf, ROCm, profiler, tool, Instinct, accelerator, shader, engine, sL1D, L1I, workgroup manager, SPI
******************
Shader engine (SE)
******************
The :doc:`compute units <compute-unit>` on a CDNA™ accelerator are grouped
together into a higher-level organizational unit called a shader engine (SE):
.. figure:: ../data/performance-model/selayout.png
:align: center
:alt: Example of CU-grouping into shader engines
:width: 800
Example of CU-grouping into shader engines on AMD Instinct MI-series
accelerators.
The number of CUs on a SE varies from chip to chip -- see for example
:hip-training-pdf:`20`. In addition, newer accelerators such as the AMD
Instinct™ MI 250X have 8 SEs per accelerator.
For the purposes of Omniperf, we consider resources that are shared between
multiple CUs on a single SE as part of the SE's metrics.
These include:
* The :ref:`scalar L1 data cache <desc-sl1d>`
* The :ref:`L1 instruction cache <desc-l1i>`
* The :ref:`workgroup manager <desc-spi>`
.. _desc-sl1d:
Scalar L1 data cache (sL1D)
===========================
The Scalar L1 Data cache (sL1D) can cache data accessed from scalar load
instructions (and scalar store instructions on architectures where they exist)
from wavefronts in the :doc:`CUs <compute-unit>`. The sL1D is shared between
multiple CUs (:gcn-crash-course:`36`) -- the exact number of CUs depends on the
architecture in question (3 CUs in GCN™ GPUs and MI100, 2 CUs in
:ref:`MI2XX <mixxx-note>`) -- and is backed by the :doc:`L2 cache <l2-cache>`.
In typical usage, the data in the sL1D is comprised of:
* Kernel arguments, such as pointers,
`non-populated <https://llvm.org/docs/AMDGPUUsage.html#amdgpu-amdhsa-sgpr-register-set-up-order-table>`_
grid and block dimensions, and others
* HIP's ``__constant__`` memory, when accessed in a provably uniform manner
[#uniform-access]_
* Other memory, when accessed in a provably uniform manner, *and* the backing
memory is provably constant [#uniform-access]_
.. _desc-sl1d-sol:
Scalar L1D Speed-of-Light
-------------------------
.. warning::
The theoretical maximum throughput for some metrics in this section are
currently computed with the maximum achievable clock frequency, as reported
by ``rocminfo``, for an accelerator. This may not be realistic for all
workloads.
The Scalar L1D speed-of-light chart shows some key metrics of the sL1D
cache as a comparison with the peak achievable values of those metrics:
.. list-table::
:header-rows: 1
:widths: 20 65 15
* - Metric
- Description
- Unit
* - Bandwidth
- The number of bytes looked up in the sL1D cache, as a percent of the peak
theoretical bandwidth. Calculated as the ratio of sL1D requests over the
:ref:`total sL1D cycles <total-sl1d-cycles>`.
- Percent
* - Cache Hit Rate
- The percent of sL1D requests that hit [#sl1d-cache]_ on a previously
loaded line in the cache. Calculated as the ratio of the number of sL1D
requests that hit over the number of all sL1D requests.
- Percent
* - sL1D-L2 BW
- The number of bytes requested by the sL1D from the L2 cache, as a percent
of the peak theoretical sL1D → L2 cache bandwidth. Calculated as the
ratio of the total number of requests from the sL1D to the L2 cache over
the :ref:`total sL1D-L2 interface cycles <total-sl1d-cycles>`.
- Percent
.. _desc-sl1d-stats:
Scalar L1D cache accesses
-------------------------
This panel gives more detail on the types of accesses made to the sL1D,
and the hit/miss statistics.
.. list-table::
:header-rows: 1
* - Metric
- Description
- Unit
* - Requests
- The total number of requests, of any size or type, made to the sL1D per
:ref:`normalization unit <normalization-units>`.
- Requests per :ref:`normalization unit <normalization-units>`
* - Hits
- The total number of sL1D requests that hit on a previously loaded cache
line, per :ref:`normalization unit <normalization-units>`.
- Requests per :ref:`normalization unit <normalization-units>`
* - Misses - Non Duplicated
- The total number of sL1D requests that missed on a cache line that *was
not* already pending due to another request, per
:ref:`normalization unit <normalization-units>`. See :ref:`desc-sl1d-sol`
for more detail.
- Requests per :ref:`normalization unit <normalization-units>`
* - Misses - Duplicated
- The total number of sL1D requests that missed on a cache line that *was*
already pending due to another request, per
:ref:`normalization unit <normalization-units>`. See
:ref:`desc-sl1d-sol` for more detail.
- Requests per :ref:`normalization unit <normalization-units>`
* - Cache Hit Rate
- Indicates the percent of sL1D requests that hit on a previously loaded
line the cache. The ratio of the number of sL1D requests that hit
[#sl1d-cache]_ over the number of all sL1D requests.
- Percent
* - Read Requests (Total)
- The total number of sL1D read requests of any size, per
:ref:`normalization unit <normalization-units>`.
- Requests per :ref:`normalization unit <normalization-units>`
* - Atomic Requests
- The total number of sL1D atomic requests of any size, per
:ref:`normalization unit <normalization-units>`. Typically unused on CDNA
accelerators.
- Requests per :ref:`normalization unit <normalization-units>`
* - Read Requests (1 DWord)
- The total number of sL1D read requests made for a single dword of data
(4B), per :ref:`normalization unit <normalization-units>`.
- Requests per :ref:`normalization unit <normalization-units>`
* - Read Requests (2 DWord)
- The total number of sL1D read requests made for a two dwords of data
(8B), per :ref:`normalization unit <normalization-units>`.
- Requests per :ref:`normalization unit <normalization-units>`
* - Read Requests (4 DWord)
- The total number of sL1D read requests made for a four dwords of data
(16B), per :ref:`normalization unit <normalization-units>`.
- Requests per :ref:`normalization unit <normalization-units>`
* - Read Requests (8 DWord)
- The total number of sL1D read requests made for a eight dwords of data
(32B), per :ref:`normalization unit <normalization-units>`.
- Requests per :ref:`normalization unit <normalization-units>`
* - Read Requests (16 DWord)
- The total number of sL1D read requests made for a sixteen dwords of data
(64B), per :ref:`normalization unit <normalization-units>`.
- Requests per :ref:`normalization unit <normalization-units>`
.. _desc-sl1d-l2-interface:
sL1D ↔ L2 Interface
-------------------
This panel gives more detail on the data requested across the
sL1D↔
:doc:`L2 <l2-cache>` interface.
.. list-table::
:header-rows: 1
* - Metric
- Description
- Unit
* - sL1D-L2 BW
- The total number of bytes read from, written to, or atomically updated
across the sL1D↔:doc:`L2 <l2-cache>` interface, per
:ref:`normalization unit <normalization-units>`. Note that sL1D writes
and atomics are typically unused on current CDNA accelerators, so in the
majority of cases this can be interpreted as an sL1D→L2 read bandwidth.
- Bytes per :ref:`normalization unit <normalization-units>`
* - Read Requests
- The total number of read requests from sL1D to the :doc:`L2 <l2-cache>`,
per :ref:`normalization unit <normalization-units>`.
- Requests per :ref:`normalization unit <normalization-units>`
* - Write Requests
- The total number of write requests from sL1D to the :doc:`L2 <l2-cache>`,
per :ref:`normalization unit <normalization-units>`. Typically unused on
current CDNA accelerators.
- Requests per :ref:`normalization unit <normalization-units>`
* - Atomic Requests
- The total number of atomic requests from sL1D to the
:doc:`L2 <l2-cache>`, per
:ref:`normalization unit <normalization-units>`. Typically unused on
current CDNA accelerators.
- Requests per :ref:`normalization unit <normalization-units>`
* - Stall Cycles
- The total number of cycles the sL1D↔
:doc:`L2 <l2-cache>` interface was stalled, per
:ref:`normalization unit <normalization-units>`.
- Cycles per :ref:`normalization unit <normalization-units>`
.. rubric:: Footnotes
.. [#uniform-access] The scalar data cache is used when the compiler emits
scalar loads to access data. This requires that the data be *provably*
uniformly accesses (that is, the compiler can verify that all work-items in a
wavefront access the same data), *and* that the data can be proven to be
read-only (for instance, HIP's ``__constant__`` memory, or properly
``__restrict__``\ed pointers to avoid write-aliasing). Access of
``__constant__`` memory for example is not guaranteed to go through the sL1D
if the wavefront loads a non-uniform value.
.. [#sl1d-cache] Unlike the :doc:`vL1D <vector-l1-cache>` and
:doc:`L2 <l2-cache>` caches, the sL1D cache on AMD Instinct MI-series CDNA
accelerators does *not* use the "hit-on-miss" approach to reporting cache
hits. That is, if while satisfying a miss, another request comes in that
would hit on the same pending cache line, the subsequent request will be
counted as a *duplicated miss*.
.. _desc-l1i:
L1 Instruction Cache (L1I)
==========================
As with the :ref:`sL1D <desc-sL1D>`, the L1 Instruction (L1I) cache is shared
between multiple CUs on a shader-engine, where the precise number of CUs
sharing a L1I depends on the architecture in question (:gcn-crash-course:`36`)
and is backed by the :doc:`L2 cache <l2-cache>`. Unlike the sL1D, the
instruction cache is read-only.
.. _desc-l1i-sol:
L1I Speed-of-Light
------------------
.. warning::
The theoretical maximum throughput for some metrics in this section are
currently computed with the maximum achievable clock frequency, as reported
by ``rocminfo``, for an accelerator. This may not be realistic for all
workloads.
The L1 Instruction Cache speed-of-light chart shows some key metrics of
the L1I cache as a comparison with the peak achievable values of those
metrics:
.. list-table::
:header-rows: 1
* - Metric
- Description
- Unit
* - Bandwidth
- The number of bytes looked up in the L1I cache, as a percent of the peak
theoretical bandwidth. Calculated as the ratio of L1I requests over the
:ref:`total L1I cycles <total-l1i-cycles>`.
- Percent
* - Cache Hit Rate
- The percent of L1I requests that hit on a previously loaded line the
cache. Calculated as the ratio of the number of L1I requests that hit
[#l1i-cache]_ over the number of all L1I requests.
- Percent
* - L1I-L2 BW
- The percent of the peak theoretical L1I → L2 cache request bandwidth
achieved. Calculated as the ratio of the total number of requests from
the L1I to the L2 cache over the
:ref:`total L1I-L2 interface cycles <total-l1i-cycles>`.
- Percent
* - Instruction Fetch Latency
- The average number of cycles spent to fetch instructions to a
:doc:`CU <compute-unit>`.
- Cycles
.. _desc-l1i-stats:
L1I cache accesses
------------------
This panel gives more detail on the hit/miss statistics of the L1I:
.. list-table::
:header-rows: 1
* - Metric
- Description
- Unit
* - Requests
- The total number of requests made to the L1I per
:ref:`normalization-unit <normalization-units>`.
- Requests per :ref:`normalization unit <normalization-units>`.
* - Hits
- The total number of L1I requests that hit on a previously loaded cache
line, per :ref:`normalization-unit <normalization-units>`.
- Requests per :ref:`normalization unit <normalization-units>`
* - Misses - Non Duplicated
- The total number of L1I requests that missed on a cache line that
*were not* already pending due to another request, per
:ref:`normalization-unit <normalization-units>`. See note in
:ref:`desc-l1i-sol` for more detail.
- Requests per :ref:`normalization unit <normalization-units>`.
* - Misses - Duplicated
- The total number of L1I requests that missed on a cache line that *were*
already pending due to another request, per
:ref:`normalization-unit <normalization-units>`. See note in
:ref:`desc-l1i-sol` for more detail.
- Requests per :ref:`normalization unit <normalization-units>`
* - Cache Hit Rate
- The percent of L1I requests that hit [#l1i-cache]_ on a previously loaded
line the cache. Calculated as the ratio of the number of L1I requests
that hit over the number of all L1I requests.
- Percent
L1I - L2 interface
------------------
This panel gives more detail on the data requested across the
L1I-:doc:`L2 <l2-cache>` interface.
.. list-table::
:header-rows: 1
* - Metric
- Description
- Unit
* - L1I-L2 BW
- The total number of bytes read across the L1I-:doc:`L2 <l2-cache>`
interface, per :ref:`normalization unit <normalization-units>`.
- Bytes per :ref:`normalization unit <normalization-units>`
.. rubric:: Footnotes
.. [#l1i-cache] Unlike the :doc:`vL1D <vector-l1-cache>` and
:doc:`L2 <l2-cache>` caches, the L1I cache on AMD Instinct MI-series CDNA
accelerators does *not* use the "hit-on-miss" approach to reporting cache
hits. That is, if while satisfying a miss, another request comes in that
would hit on the same pending cache line, the subsequent request will be
counted as a *duplicated miss*.
.. _desc-spi:
Workgroup manager (SPI)
=======================
The workgroup manager (SPI) is the bridge between the
:doc:`command processor <command-processor>` and the
:doc:`compute units <compute-unit>`. After the command processor processes a
kernel dispatch, it will then pass the dispatch off to the workgroup manager,
which then schedules :ref:`workgroups <desc-workgroup>` onto the compute units.
As workgroups complete execution and resources become available, the
workgroup manager will schedule new workgroups onto compute units. The workgroup
manager’s metrics therefore are focused on reporting the following:
* Utilizations of various parts of the accelerator that the workgroup
manager interacts with (and the workgroup manager itself)
* How many workgroups were dispatched, their size, and how many
resources they used
* Percent of scheduler opportunities (cycles) where workgroups failed
to dispatch, and
* Percent of scheduler opportunities (cycles) where workgroups failed
to dispatch due to lack of a specific resource on the CUs (for instance, too
many VGPRs allocated)
This gives you an idea of why the workgroup manager couldn’t schedule more
wavefronts onto the device, and is most useful for workloads that you suspect to
be limited by scheduling or launch rate.
As discussed in :doc:`Command processor <command-processor>`, the command
processor on AMD Instinct MI-series architectures contains four hardware
scheduler-pipes, each with eight software threads (:mantor-vega10-pdf:`19`). Each
scheduler-pipe can issue a kernel dispatch to the workgroup manager to schedule
concurrently. Therefore, some workgroup manager metrics are presented relative
to the utilization of these scheduler-pipes (for instance, whether all four are
issuing concurrently).
.. note::
Current versions of the profiling libraries underlying Omniperf attempt to
serialize concurrent kernels running on the accelerator, as the performance
counters on the device are global (that is, shared between concurrent
kernels). This means that these scheduler-pipe utilization metrics are
expected to reach (for example) a maximum of one pipe active -- only 25%.
Workgroup manager utilizations
------------------------------
This section describes the utilization of the workgroup manager, and the
hardware components it interacts with.
.. list-table::
:header-rows: 1
:widths: 20 65 15
* - Metric
- Description
- Unit
* - Accelerator utilization
- The percent of cycles in the kernel where the accelerator was actively
doing any work.
- Percent
* - Scheduler-pipe utilization
- The percent of :ref:`total scheduler-pipe cycles <total-pipe-cycles>` in
the kernel where the scheduler-pipes were actively doing any work. Note:
this value is expected to range between 0% and 25%. See :ref:`desc-spi`.
- Percent
* - Workgroup manager utilization
- The percent of cycles in the kernel where the workgroup manager was
actively doing any work.
- Percent
* - Shader engine utilization
- The percent of :ref:`total shader engine cycles <total-se-cycles>` in the
kernel where any CU in a shader-engine was actively doing any work,
normalized over all shader-engines. Low values (e.g., << 100%) indicate
that the accelerator was not fully saturated by the kernel, or a
potential load-imbalance issue.
- Percent
* - SIMD utilization
- The percent of :ref:`total SIMD cycles <total-simd-cycles>` in the kernel
where any :ref:`SIMD <desc-valu>` on a CU was actively doing any work,
summed over all CUs. Low values (less than 100%) indicate that the
accelerator was not fully saturated by the kernel, or a potential
load-imbalance issue.
- Percent
* - Dispatched workgroups
- The total number of workgroups forming this kernel launch.
- Workgroups
* - Dispatched wavefronts
- The total number of wavefronts, summed over all workgroups, forming this
kernel launch.
- Wavefronts
* - VGPR writes
- The average number of cycles spent initializing :ref:`VGPRs <desc-valu>`
at wave creation.
- Cycles/wave
* - SGPR Writes
- The average number of cycles spent initializing :ref:`SGPRs <desc-salu>`
at wave creation.
- Cycles/wave
Resource allocation
-------------------
This panel gives more detail on how workgroups and wavefronts were scheduled
onto compute units, and what occupancy limiters they hit -- if any. When
analyzing these metrics, you should also take into account their
achieved occupancy -- such as
:ref:`wavefront occupancy <wavefront-runtime-stats>`. A kernel may be occupancy
limited by LDS usage, for example, but may still achieve high occupancy levels
such that improving occupancy further may not improve performance. See
:ref:`occupancy-example` for details.
.. list-table::
:header-rows: 1
* - Metric
- Description
- Unit
* - Not-scheduled rate (Workgroup Manager)
- The percent of :ref:`total scheduler-pipe cycles <total-pipe-cycles>` in
the kernel where a workgroup could not be scheduled to a
:doc:`CU <compute-unit>` due to a bottleneck within the workgroup manager
rather than a lack of a CU or :ref:`SIMD <desc-valu>` with sufficient
resources. Note: this value is expected to range between 0-25%. See note
in :ref:`workgroup manager <desc-spi>` description.
- Percent
* - Not-scheduled rate (Scheduler-Pipe)
- The percent of :ref:`total scheduler-pipe cycles <total-pipe-cycles>` in
the kernel where a workgroup could not be scheduled to a
:doc:`CU <compute-unit>` due to a bottleneck within the scheduler-pipes
rather than a lack of a CU or :ref:`SIMD <desc-valu>` with sufficient
resources. Note: this value is expected to range between 0-25%, see note
in :ref:`workgroup manager <desc-spi>` description.
- Percent
* - Scheduler-Pipe Stall Rate
- The percent of :ref:`total scheduler-pipe cycles <total-pipe-cycles>` in
the kernel where a workgroup could not be scheduled to a
:doc:`CU <compute-unit>` due to occupancy limitations (like a lack of a
CU or :ref:`SIMD <desc-valu>` with sufficient resources). Note: this
value is expected to range between 0-25%, see note in
:ref:`workgroup manager <desc-spi>` description.
- Percent
* - Scratch Stall Rate
- The percent of :ref:`total shader-engine cycles <total-se-cycles>` in the
kernel where a workgroup could not be scheduled to a
:doc:`CU <compute-unit>` due to lack of
:ref:`private (a.k.a., scratch) memory <memory-type>` slots. While this
can reach up to 100%, note that the actual occupancy limitations on a
kernel using private memory are typically quite small (for example, less
than 1% of the total number of waves that can be scheduled to an
accelerator).
- Percent
* - Insufficient SIMD Waveslots
- The percent of :ref:`total SIMD cycles <total-simd-cycles>` in the kernel
where a workgroup could not be scheduled to a :ref:`SIMD <desc-valu>`
due to lack of available :ref:`waveslots <desc-valu>`.
- Percent
* - Insufficient SIMD VGPRs
- The percent of :ref:`total SIMD cycles <total-simd-cycles>` in the kernel
where a workgroup could not be scheduled to a :ref:`SIMD <desc-valu>`
due to lack of available :ref:`VGPRs <desc-valu>`.
- Percent
* - Insufficient SIMD SGPRs
- The percent of :ref:`total SIMD cycles <total-simd-cycles>` in the kernel
where a workgroup could not be scheduled to a :ref:`SIMD <desc-valu>`
due to lack of available :ref:`SGPRs <desc-salu>`.
- Percent
* - Insufficient CU LDS
- The percent of :ref:`total CU cycles <total-cu-cycles>` in the kernel
where a workgroup could not be scheduled to a :doc:`CU <compute-unit>`
due to lack of available :doc:`LDS <local-data-share>`.
- Percent
* - Insufficient CU Barriers
- The percent of :ref:`total CU cycles <total-cu-cycles>` in the kernel
where a workgroup could not be scheduled to a :doc:`CU <compute-unit>`
due to lack of available :ref:`barriers <desc-barrier>`.
- Percent
* - Reached CU Workgroup Limit
- The percent of :ref:`total CU cycles <total-cu-cycles>` in the kernel
where a workgroup could not be scheduled to a :doc:`CU <compute-unit>`
due to limits within the workgroup manager. This is expected to be
always be zero on CDNA2 or newer accelerators (and small for previous
accelerators).
- Percent
* - Reached CU Wavefront Limit
- The percent of :ref:`total CU cycles <total-cu-cycles>` in the kernel
where a wavefront could not be scheduled to a :doc:`CU <compute-unit>`
due to limits within the workgroup manager. This is expected to be
always be zero on CDNA2 or newer accelerators (and small for previous
accelerators).
- Percent
+318
View File
@@ -0,0 +1,318 @@
.. meta::
:description: Omniperf performance model: System Speed-of-Light
:keywords: Omniperf, ROCm, profiler, tool, Instinct, accelerator, AMD, system, speed of light
*********************
System Speed-of-Light
*********************
System Speed-of-Light summarizes some of the key metrics from various sections
of Omniperf’s profiling report.
.. warning::
The theoretical maximum throughput for some metrics in this section are
currently computed with the maximum achievable clock frequency, as reported
by ``rocminfo``, for an accelerator. This may not be realistic for
all workloads.
Also, not all metrics -- such as FLOP counters -- are available on all AMD
Instinct™ MI-series accelerators. For more detail on how operations are
counted, see the :ref:`metrics-flop-count` section.
.. list-table::
:header-rows: 1
* - Metric
- Description
- Unit
* - :ref:`VALU <desc-valu>` FLOPs
- The total floating-point operations executed per second on the
:ref:`VALU <desc-valu>`. This is also presented as a percent of the peak
theoretical FLOPs achievable on the specific accelerator. Note: this does
not include any floating-point operations from :ref:`MFMA <desc-mfma>`
instructions.
- GFLOPs
* - :ref:`VALU <desc-valu>` IOPs
- The total integer operations executed per second on the
:ref:`VALU <desc-valu>`. This is also presented as a percent of the peak
theoretical IOPs achievable on the specific accelerator. Note: this does
not include any integer operations from :ref:`MFMA <desc-mfma>`
instructions.
- GIOPs
* - :ref:`MFMA <desc-mfma>` FLOPs (BF16)
- The total number of 16-bit brain floating point :ref:`MFMA <desc-mfma>`
operations executed per second. Note: this does not include any 16-bit
brain floating point operations from :ref:`VALU <desc-valu>`
instructions. This is also presented as a percent of the peak theoretical
BF16 MFMA operations achievable on the specific accelerator.
- GFLOPs
* - :ref:`MFMA <desc-mfma>` FLOPs (F16)
- The total number of 16-bit floating point :ref:`MFMA <desc-mfma>`
operations executed per second. Note: this does not include any 16-bit
floating point operations from :ref:`VALU <desc-valu>` instructions. This
is also presented as a percent of the peak theoretical F16 MFMA
operations achievable on the specific accelerator.
- GFLOPs
* - :ref:`MFMA <desc-mfma>` FLOPs (F32)
- The total number of 32-bit floating point :ref:`MFMA <desc-mfma>`
operations executed per second. Note: this does not include any 32-bit
floating point operations from :ref:`VALU <desc-valu>` instructions. This
is also presented as a percent of the peak theoretical F32 MFMA
operations achievable on the specific accelerator.
- GFLOPs
* - :ref:`MFMA <desc-mfma>` FLOPs (F64)
- The total number of 64-bit floating point :ref:`MFMA <desc-mfma>`
operations executed per second. Note: this does not include any 64-bit
floating point operations from :ref:`VALU <desc-valu>` instructions. This
is also presented as a percent of the peak theoretical F64 MFMA
operations achievable on the specific accelerator.
- GFLOPs
* - :ref:`MFMA <desc-mfma>` IOPs (INT8)
- The total number of 8-bit integer :ref:`MFMA <desc-mfma>` operations
executed per second. Note: this does not include any 8-bit integer
operations from :ref:`VALU <desc-valu>` instructions. This is also
presented as a percent of the peak theoretical INT8 MFMA operations
achievable on the specific accelerator.
- GIOPs
* - :ref:`SALU <desc-salu>` utilization
- Indicates what percent of the kernel's duration the
:ref:`SALU <desc-salu>` was busy executing instructions. Computed as the
ratio of the total number of cycles spent by the
:ref:`scheduler <desc-scheduler>` issuing :ref:`SALU <desc-salu>` or
:ref:`SMEM <desc-salu>` instructions over the
:ref:`total CU cycles <total-cu-cycles>`.
- Percent
* - :ref:`VALU <desc-valu>` utilization
- Indicates what percent of the kernel's duration the
:ref:`VALU <desc-valu>` was busy executing instructions. Does not include
:ref:`VMEM <desc-vmem>` operations. Computed as the ratio of the total
number of cycles spent by the :ref:`scheduler <desc-scheduler>` issuing
:ref:`VALU <desc-valu>` instructions over the
:ref:`total CU cycles <total-cu-cycles>`.
- Percent
* - :ref:`MFMA <desc-mfma>` utilization
- Indicates what percent of the kernel's duration the
:ref:`MFMA <desc-mfma>` unit was busy executing instructions. Computed as
the ratio of the total number of cycles the MFMA was busy over the
:ref:`total CU cycles <total-cu-cycles>`.
- Percent
* - :ref:`VMEM <desc-valu>` utilization
- Indicates what percent of the kernel's duration the
:ref:`VMEM <desc-valu>` unit was busy executing instructions, including
both global/generic and spill/scratch operations (see the
:ref:`VMEM instruction count metrics <ta-instruction-counts>`) for more
detail). Does not include :ref:`VALU <desc-valu>` operations. Computed as
the ratio of the total number of cycles spent by the
:ref:`scheduler <desc-scheduler>` issuing VMEM instructions over the
:ref:`total CU cycles <total-cu-cycles>`.
- Percent
* - :ref:`Branch <desc-branch>` utilization
- Indicates what percent of the kernel's duration the
:ref:`branch <desc-branch>` unit was busy executing instructions.
Computed as the ratio of the total number of cycles spent by the
:ref:`scheduler <desc-scheduler>` issuing :ref:`branch <desc-branch>`
instructions over the :ref:`total CU cycles <total-cu-cycles>`
- Percent
* - :ref:`VALU <desc-valu>` active threads
- Indicates the average level of :ref:`divergence <desc-divergence>` within
a wavefront over the lifetime of the kernel. The number of work-items
that were active in a wavefront during execution of each
:ref:`VALU <desc-valu>` instruction, time-averaged over all VALU
instructions run on all wavefronts in the kernel.
- Work-items
* - IPC
- The ratio of the total number of instructions executed on the
:doc:`CU <compute-unit>` over the
:ref:`total active CU cycles <total-active-cu-cycles>`. This is also
presented as a percent of the peak theoretical bandwidth achievable on
the specific accelerator.
- Instructions per-cycle
* - Wavefront occupancy
- The time-averaged number of wavefronts resident on the accelerator over
the lifetime of the kernel. Note: this metric may be inaccurate for
short-running kernels (less than 1ms). This is also presented as a
percent of the peak theoretical occupancy achievable on the specific
accelerator.
- Wavefronts
* - :doc:`LDS <local-data-share>` theoretical bandwidth
- Indicates the maximum amount of bytes that could have been loaded from,
stored to, or atomically updated in the LDS per unit time (see
:ref:`LDS Bandwidth <lds-bandwidth>` example for more detail). This is
also presented as a percent of the peak theoretical F64 MFMA operations
achievable on the specific accelerator.
- GB/s
* - :doc:`LDS <local-data-share>` bank conflicts/access
- The ratio of the number of cycles spent in the
:doc:`LDS scheduler <local-data-share>` due to bank conflicts (as
determined by the conflict resolution hardware) to the base number of
cycles that would be spent in the LDS scheduler in a completely
uncontended case. This is also presented in normalized form (i.e., the
Bank Conflict Rate).
- Conflicts/Access
* - :doc:`vL1D <vector-l1-cache>` cache hit rate
- The ratio of the number of vL1D cache line requests that hit in vL1D
cache over the total number of cache line requests to the
:ref:`vL1D cache RAM <desc-tc>`.
- Percent
* - :doc:`vL1D <vector-l1-cache>` cache bandwidth
- The number of bytes looked up in the vL1D cache as a result of
:ref:`VMEM <desc-vmem>` instructions per unit time. The number of bytes
is calculated as the number of cache lines requested multiplied by the
cache line size. This value does not consider partial requests, so e.g.,
if only a single value is requested in a cache line, the data movement
will still be counted as a full cache line. This is also presented as a
percent of the peak theoretical bandwidth achievable on the specific
accelerator.
- GB/s
* - :doc:`L2 <l2-cache>` cache hit rate
- The ratio of the number of L2 cache line requests that hit in the L2
cache over the total number of incoming cache line requests to the L2
cache.
- Percent
* - :doc:`L2 <l2-cache>` cache bandwidth
- The number of bytes looked up in the L2 cache per unit time. The number
of bytes is calculated as the number of cache lines requested multiplied
by the cache line size. This value does not consider partial requests, so
e.g., if only a single value is requested in a cache line, the data
movement will still be counted as a full cache line. This is also
presented as a percent of the peak theoretical bandwidth achievable on
the specific accelerator.
- GB/s
* - :doc:`L2 <l2-cache>`-fabric read BW
- The number of bytes read by the L2 over the
:ref:`Infinity Fabric™ interface <l2-fabric>` per unit time. This is also
presented as a percent of the peak theoretical bandwidth achievable on
the specific accelerator.
- GB/s
* - :doc:`L2 <l2-cache>`-fabric write and atomic BW
- The number of bytes sent by the L2 over the
:ref:`Infinity Fabric interface <l2-fabric>` by write and atomic
operations per unit time. This is also presented as a percent of the peak
theoretical bandwidth achievable on the specific accelerator.
- GB/s
* - :doc:`L2 <l2-cache>`-fabric read latency
- The time-averaged number of cycles read requests spent in Infinity Fabric
before data was returned to the L2.
- Cycles
* - :doc:`L2 <l2-cache>`-fabric write latency
- The time-averaged number of cycles write requests spent in Infinity
Fabric before a completion acknowledgement was returned to the L2.
- Cycles
* - :ref:`sL1D <desc-sl1d>` cache hit rate
- The percent of sL1D requests that hit on a previously loaded line the
cache. Calculated as the ratio of the number of sL1D requests that hit
over the number of all sL1D requests.
- Percent
* - :ref:`sL1D <desc-sl1d>` bandwidth
- The number of bytes looked up in the sL1D cache per unit time. This is
also presented as a percent of the peak theoretical bandwidth achievable
on the specific accelerator.
- GB/s
* - :ref:`L1I <desc-l1i>` bandwidth
- The number of bytes looked up in the L1I cache per unit time. This is
also presented as a percent of the peak theoretical bandwidth achievable
on the specific accelerator.
- GB/s
* - :ref:`L1I <desc-l1i>` cache hit rate
- The percent of L1I requests that hit on a previously loaded line the
cache. Calculated as the ratio of the number of L1I requests that hit
over the number of all L1I requests.
- Percent
* - :ref:`L1I <desc-l1i>` fetch latency
- The average number of cycles spent to fetch instructions to a
:doc:`CU <compute-unit>`.
- Cycles
+767
View File
@@ -0,0 +1,767 @@
.. meta::
:description: Omniperf performance model: Vector L1 cache (vL1D)
:keywords: Omniperf, ROCm, profiler, tool, Instinct, accelerator, AMD, vector, l1, cache, vl1d
**********************
Vector L1 cache (vL1D)
**********************
The vector L1 data (vL1D) cache is local to each
:doc:`compute unit <compute-unit>` on the accelerator, and handles vector memory
operations issued by a wavefront. The vL1D cache consists of several components:
* An address processing unit, also known as the
:ref:`texture addresser <desc-ta>` which receives commands (instructions) and
write/atomic data from the :doc:`compute unit <compute-unit>`, and coalesces
them into fewer requests for the cache to process.
* An address translation unit, also known as the
:ref:`L1 Unified Translation Cache (UTCL1) <desc-utcl1>`, that translates
requests from virtual to physical addresses for lookup in the cache. The
translation unit has an L1 translation lookaside buffer (L1TLB) to reduce the
cost of repeated translations.
* A Tag RAM that looks up whether a requested cache line is already
present in the :ref:`cache <desc-tc>`.
* The result of the Tag RAM lookup is placed in the L1 cache controller
for routing to the correct location; for instance, the
:ref:`L2 Memory Interface <vl1d-l2-transaction-detail>` for misses or the
:ref:`cache RAM <desc-tc>` for hits.
* The cache RAM, also known as the :ref:`texture cache (TC) <desc-tc>`, stores
requested data for potential reuse. Data returned from the
:doc:`L2 cache <l2-cache>` is placed into the cache RAM before going down the
:ref:`data-return path <desc-td>`.
* A backend data processing unit, also known as the
:ref:`texture data (TD) <desc-td>` that routes data back to the requesting
:doc:`compute unit <compute-unit>`.
Together, this complex is known as the vL1D, or Texture Cache per Pipe
(TCP). A simplified diagram of the vL1D is presented below:
.. figure:: ../data/performance-model/l1perf_model.png
:align: center
:alt: Performance model of the vL1D Cache on AMD Instinct
:width: 800
Performance model of the vL1D Cache on AMD Instinct MI-series accelerators.
.. _vl1d-sol:
vL1D Speed-of-Light
===================
.. warning::
The theoretical maximum throughput for some metrics in this section are
currently computed with the maximum achievable clock frequency, as reported
by ``rocminfo``, for an accelerator. This may not be realistic for all
workloads.
The vL1D’s speed-of-light chart shows several key metrics for the vL1D
as a comparison with the peak achievable values of those metrics.
.. list-table::
:header-rows: 1
* - Metric
- Description
- Unit
* - Hit Rate
- The ratio of the number of vL1D cache line requests that hit [#vl1d-hit]_
in vL1D cache over the total number of cache line requests to the
:ref:`vL1D Cache RAM <desc-tc>`.
- Percent
* - Bandwidth
- The number of bytes looked up in the vL1D cache as a result of
:ref:`VMEM <desc-vmem>` instructions, as a percent of the peak
theoretical bandwidth achievable on the specific accelerator. The number
of bytes is calculated as the number of cache lines requested multiplied
by the cache line size. This value does not consider partial requests, so
for instance, if only a single value is requested in a cache line, the
data movement will still be counted as a full cache line.
- Percent
* - Utilization
- Indicates how busy the :ref:`vL1D Cache RAM <desc-tc>` was during the
kernel execution. The number of cycles where the vL1D Cache RAM is
actively processing any request divided by the number of cycles where the
vL1D is active [#vl1d-activity]_.
- Percent
* - Coalescing
- Indicates how well memory instructions were coalesced by the
:ref:`address processing unit <desc-ta>`, ranging from uncoalesced (25%)
to fully coalesced (100%). Calculated as the average number of
:ref:`thread-requests <thread-requests>` generated per instruction
divided by the ideal number of thread-requests per instruction.
- Percent
.. _desc-ta:
Address processing unit or Texture Addresser (TA)
=================================================
The :doc:`vL1D <vector-l1-cache>`’s address processing unit receives vector
memory instructions (commands) along with write/atomic data from a
:doc:`compute unit <compute-unit>` and is responsible for coalescing these into
requests for lookup in the :ref:`vL1D RAM <desc-tc>`. The address processor
passes information about the commands (coalescing state, destination SIMD,
etc.) to the :ref:`data processing unit <desc-td>` for use after the requested
data has been retrieved.
Omniperf reports several metrics to indicate performance bottlenecks in
the address processing unit, which are broken down into a few
categories:
- :ref:`ta-busy-stall`
- :ref:`ta-instruction-counts`
- :ref:`ta-spill-stack`
.. _ta-busy-stall:
Busy / stall metrics
--------------------
When executing vector memory instructions, the compute unit must send an
address (and in the case of writes/atomics, data) to the address
processing unit. When the front-end cannot accept any more addresses, it
must backpressure the wave-issue logic for the VMEM pipe and prevent the
issue of further vector memory instructions.
.. list-table::
:header-rows: 1
* - Metric
- Description
- Unit
* - Busy
- Percent of the :ref:`total CU cycles <total-cu-cycles>` the address
processor was busy
- Percent
* - Address Stall
- Percent of the :ref:`total CU cycles <total-cu-cycles>` the address
processor was stalled from sending address requests further into the vL1D
pipeline
- Percent
* - Data Stall
- Percent of the :ref:`total CU cycles <total-cu-cycles>` the address
processor was stalled from sending write/atomic data further into the
vL1D pipeline
- Percent
* - Data-Processor → Address Stall
- Percent of :ref:`total CU cycles <total-cu-cycles>` the address processor
was stalled waiting to send command data to the
:ref:`data processor <desc-td>`
- Percent
.. _ta-instruction-counts:
Instruction counts
------------------
The address processor also counts instruction types to give the user
information on what sorts of memory instructions were executed by the
kernel. These are broken down into a few major categories:
.. list-table::
:header-rows: 1
* - Memory type
- Usage
- Description
* - Global
- Global memory
- Global memory can be seen by all threads from a process. This includes
the local accelerator's DRAM, remote accelerator's DRAM, and the host's
DRAM.
* - Generic
- Dynamic address spaces
- Generic memory, or "flat" memory, is used when the compiler cannot
statically prove that a pointer is to memory in one or the other address
spaces. The pointer could dynamically point into global, local, constant,
or private memory.
* - Private Memory
- Register spills / Stack memory
- Private memory, or "scratch" memory, is only visible to a particular
:ref:`work-item <desc-work-item>` in a particular
:ref:`workgroup <desc-workgroup>`. On AMD Instinct™ MI-series
accelerators, private memory is used to implement both register spills
and stack memory accesses.
The address processor counts these instruction types as follows:
.. list-table::
:header-rows: 1
* - Type
- Description
- Unit
* - Global/Generic
- The total number of global & generic memory instructions executed on all
:doc:`compute units <compute-unit>` on the accelerator, per
:ref:`normalization unit <normalization-units>`.
- Instructions per :ref:`normalization unit <normalization-units>`
* - Global/Generic Read
- The total number of global & generic memory read instructions executed on
all :doc:`compute units <compute-unit>` on the accelerator, per
:ref:`normalization unit <normalization-units>`.
- Instructions per :ref:`normalization unit <normalization-units>`
* - Global/Generic Write
- The total number of global & generic memory write instructions executed
on all :doc:`compute units <compute-unit>` on the accelerator, per
:ref:`normalization unit <normalization-units>`.
- Instructions per :ref:`normalization unit <normalization-units>`
* - Global/Generic Atomic
- The total number of global & generic memory atomic (with and without
return) instructions executed on all :doc:`compute units <compute-unit>`
on the accelerator, per :ref:`normalization unit <normalization-units>`.
- Instructions per :ref:`normalization unit <normalization-units>`
* - Spill/Stack
- The total number of spill/stack memory instructions executed on all
:doc:`compute units <compute-unit>` on the accelerator, per
:ref:`normalization unit <normalization-units>`.
- Instructions per :ref:`normalization unit <normalization-units>`
* - Spill/Stack Read
- The total number of spill/stack memory read instructions executed on all
:doc:`compute units <compute-unit>` on the accelerator, per
:ref:`normalization unit <normalization-units>`.
- Instructions per :ref:`normalization unit <normalization-units>`
* - Spill/Stack Write
- The total number of spill/stack memory write instructions executed on all
:doc:`compute units <compute-unit>` on the accelerator, per
:ref:`normalization unit <normalization-units>`.
- Instruction per :ref:`normalization unit <normalization-units>`
* - Spill/Stack Atomic
- The total number of spill/stack memory atomic (with and without return)
instructions executed on all :doc:`compute units <compute-unit>` on the
accelerator, per :ref:`normalization unit <normalization-units>`.
Typically unused as these memory operations are typically used to
implement thread-local storage.
- Instructions per :ref:`normalization unit <normalization-units>`
.. note::
The above is a simplified model specifically for the HIP programming language
that does not consider inline assembly usage, constant memory usage or
texture memory.
These categories correspond to:
* Global/Generic: global and flat memory operations, that are used for global
and generic memory access.
* Spill/Stack: buffer instructions which are used on the MI50, MI100, and
:ref:`MI2XX <mixxx-note>` accelerators for register spills / stack memory.
These concepts are described in more detail in the :ref:`memory-spaces`,
while generic memory access is explored in the
:ref:`generic memory benchmark <flat-memory-ex>` section.
.. _ta-spill-stack:
Spill / stack metrics
---------------------
Finally, the address processing unit contains a separate coalescing
stage for spill/stack memory, and thus reports:
.. list-table::
:header-rows: 1
* - Metric
- Description
- Unit
* - Spill/Stack Total Cycles
- The number of cycles the address processing unit spent working on
spill/stack instructions, per
:ref:`normalization unit <normalization-units>`.
- Cycles per :ref:`normalization unit <normalization-units>`
* - Spill/Stack Coalesced Read Cycles
- The number of cycles the address processing unit spent working on
coalesced spill/stack read instructions, per
:ref:`normalization unit <normalization-units>`.
- Cycles per :ref:`normalization unit <normalization-units>`
* - Spill/Stack Coalesced Write Cycles
- The number of cycles the address processing unit spent working on
coalesced spill/stack write instructions, per
:ref:`normalization unit <normalization-units>`.
- Cycles per :ref:`normalization unit <normalization-units>`
.. _desc-utcl1:
L1 Unified Translation Cache (UTCL1)
====================================
After a vector memory instruction has been processed/coalesced by the
address processing unit of the vL1D, it must be translated from a
virtual to physical address. This process is handled by the L1 Unified
Translation Cache (UTCL1). This cache contains a L1 Translation
Lookaside Buffer (TLB) which stores recently translated addresses to
reduce the cost of subsequent re-translations.
Omniperf reports the following L1 TLB metrics:
.. list-table::
:header-rows: 1
* - Metric
- Description
- Unit
* - Requests
- The number of translation requests made to the UTCL1 per
:ref:`normalization unit <normalization-units>`.
- Requests per :ref:`normalization unit <normalization-units>`
* - Hits
- The number of translation requests that hit in the UTCL1, and could be
reused, per :ref:`normalization unit <normalization-units>`.
- Requests per :ref:`normalization unit <normalization-units>`
* - Hit Ratio
- The ratio of the number of translation requests that hit in the UTCL1
divided by the total number of translation requests made to the UTCL1.
- Percent
* - Translation Misses
- The total number of translation requests that missed in the UTCL1 due to
translation not being present in the cache, per
:ref:`normalization unit <normalization-units>`.
- Requests per :ref:`normalization unit <normalization-units>`
* - Permission Misses
- The total number of translation requests that missed in the UTCL1 due to
a permission error, per :ref:`normalization unit <normalization-units>`.
This is unused and expected to be zero in most configurations for modern
CDNA™ accelerators.
- Requests per :ref:`normalization unit <normalization-units>`
.. note::
On current CDNA accelerators, such as the :ref:`MI2XX <mixxx-note>`, the
UTCL1 does *not* count hit-on-miss requests.
.. _desc-tc:
Vector L1 Cache RAM or Texture Cache (TC)
=========================================
After coalescing in the :ref:`address processing unit <desc-ta>` of the v1LD,
and address translation in the :ref:`L1 TLB <desc-utcl1>` the request proceeds
to the Cache RAM stage of the pipeline. Incoming requests are looked up
in the cache RAMs using parts of the physical address as a tag. Hits
will be returned through the :ref:`data-return path <desc-td>`, while misses
will routed out to the :doc:`L2 Cache <l2-cache>` for servicing.
The metrics tracked by the vL1D RAM include:
- :ref:`Stall metrics <vl1d-cache-stall-metrics>`
- :ref:`Cache access metrics <vl1d-cache-access-metrics>`
- :ref:`vL1D-L2 transaction detail metrics <vl1d-l2-transaction-detail>`
.. _vl1d-cache-stall-metrics:
vL1D cache stall metrics
------------------------
The vL1D also reports where it is stalled in the pipeline, which may
indicate performance limiters of the cache. A stall in the pipeline may
result in backpressuring earlier parts of the pipeline, e.g., a stall on
L2 requests may backpressure the wave-issue logic of the :ref:`VMEM <desc-vmem>`
pipe and prevent it from issuing more vector memory instructions until
the vL1D’s outstanding requests are completed.
.. list-table::
:header-rows: 1
* - Metric
- Description
- Unit
* - Stalled on L2 Data
- The ratio of the number of cycles where the vL1D is stalled waiting for
requested data to return from the :doc:`L2 cache <l2-cache>` divided by
the number of cycles where the vL1D is active [#vl1d-activity]_.
- Percent
* - Stalled on L2 Requests
- The ratio of the number of cycles where the vL1D is stalled waiting to
issue a request for data to the :doc:`L2 cache <l2-cache>` divided by the
number of cycles where the vL1D is active [#vl1d-activity]_.
- Percent
* - Tag RAM Stall (Read/Write/Atomic)
- The ratio of the number of cycles where the vL1D is stalled due to
Read/Write/Atomic requests with conflicting tags being looked up
concurrently, divided by the number of cycles where the
vL1D is active [#vl1d-activity]_.
- Percent
.. _vl1d-cache-access-metrics:
vL1D cache access metrics
-------------------------
The vL1D cache access metrics broadly indicate the type of requests
incoming from the :ref:`cache front-end <desc-ta>`, the number of requests that
were serviced by the vL1D, and the number & type of outgoing requests to
the :doc:`L2 cache <l2-cache>`. In addition, this section includes the
approximate latencies of accesses to the cache itself, along with
latencies of read/write memory operations to the :doc:`L2 cache <l2-cache>`.
.. list-table::
:header-rows: 1
* - Metric
- Description
- Unit
* - Total Requests
- The total number of incoming requests from the
:ref:`address processing unit <desc-ta>` after coalescing.
- Requests
* - Total read/write/atomic requests
- The total number of incoming read/write/atomic requests from the
:ref:`address processing unit <desc-ta>` after coalescing per
:ref:`normalization unit <normalization-units>`
- Requests per :ref:`normalization unit <normalization-units>`
* - Cache Bandwidth
- The number of bytes looked up in the vL1D cache as a result of
:ref:`VMEM <desc-vmem>` instructions per
:ref:`normalization unit <normalization-units>`. The number of bytes is
calculated as the number of cache lines requested multiplied by the cache
line size. This value does not consider partial requests, so for
instance, if only a single value is requested in a cache line, the data
movement will still be counted as a full cache line.
- Bytes per :ref:`normalization unit <normalization-units>`
* - Cache Hit Rate [#vl1d-hit]_
- The ratio of the number of vL1D cache line requests that hit in vL1D
cache over the total number of cache line requests to the
:ref:`vL1D Cache RAM <desc-tc>`.
- Percent
* - Cache Accesses
- The total number of cache line lookups in the vL1D.
- Cache lines
* - Cache Hits [#vl1d-hit]_
- The number of cache accesses minus the number of outgoing requests to the
:doc:`L2 cache <l2-cache>`, that is, the number of cache line requests
serviced by the :ref:`vL1D Cache RAM <desc-tc>` per
:ref:`normalization unit <normalization-units>`.
- Cache lines per :ref:`normalization unit <normalization-units>`
* - Invalidations
- The number of times the vL1D was issued a write-back invalidate command
during the kernel's execution per
:ref:`normalization unit <normalization-units>`. This may be triggered
by, for instance, the ``buffer_wbinvl1`` instruction.
- Invalidations per :ref:`normalization unit <normalization-units>`
* - L1-L2 Bandwidth
- The number of bytes transferred across the vL1D-L2 interface as a result
of :ref:`VMEM <desc-vmem>` instructions, per
:ref:`normalization unit <normalization-units>`. The number of bytes is
calculated as the number of cache lines requested multiplied by the cache
line size. This value does not consider partial requests, so for
instance, if only a single value is requested in a cache line, the data
movement will still be counted as a full cache line.
- Bytes per :ref:`normalization unit <normalization-units>`
* - L1-L2 Reads
- The number of read requests for a vL1D cache line that were not satisfied
by the vL1D and must be retrieved from the to the
:doc:`L2 Cache <l2-cache>` per
:ref:`normalization unit <normalization-units>`.
- Requests per :ref:`normalization unit <normalization-units>`
* - L1-L2 Writes
- The number of write requests to a vL1D cache line that were sent through
the vL1D to the :doc:`L2 cache <l2-cache>`, per
:ref:`normalization unit <normalization-units>`.
- Requests per :ref:`normalization unit <normalization-units>`
* - L1-L2 Atomics
- The number of atomic requests that are sent through the vL1D to the
:doc:`L2 cache <l2-cache>`, per
:ref:`normalization unit <normalization-units>`. This includes requests
for atomics with, and without return.
- Requests per :ref:`normalization unit <normalization-units>`
* - L1 Access Latency
- Calculated as the average number of cycles that a vL1D cache line request
spent in the vL1D cache pipeline.
- Cycles
* - L1-L2 Read Access Latency
- Calculated as the average number of cycles that the vL1D cache took to
issue and receive read requests from the :doc:`L2 Cache <l2-cache>`. This
number also includes requests for atomics with return values.
- Cycles
* - L1-L2 Write Access Latency
- Calculated as the average number of cycles that the vL1D cache took to
issue and receive acknowledgement of a write request to the
:doc:`L2 Cache <l2-cache>`. This number also includes requests for
atomics without return values.
- Cycles
.. note::
All cache accesses in vL1D are for a single cache line's worth of data.
The size of a cache line may vary, however on current AMD Instinct MI CDNA
accelerators and GCN™ GPUs the L1 cache line size is 64B.
.. rubric :: Footnotes
.. [#vl1d-hit] The vL1D cache on AMD Instinct MI-series CDNA accelerators
uses a "hit-on-miss" approach to reporting cache hits. That is, if while
satisfying a miss, another request comes in that would hit on the same
pending cache line, the subsequent request will be counted as a "hit".
Therefore, it is also important to consider the access latency metric in the
:ref:`Cache access metrics <vl1d-cache-stall-metrics>` section when
evaluating the vL1D hit rate.
.. [#vl1d-activity] Omniperf considers the vL1D to be active when any part of
the vL1D (excluding the :ref:`address processor <desc-ta>` and
:ref:`data return <desc-td>` units) are active, for example, when performing
a translation, waiting for data, accessing the Tag or Cache RAMs, etc.
.. _vl1d-l2-transaction-detail:
vL1D - L2 Transaction Detail
----------------------------
This section provides a more granular look at the types of requests made
to the :doc:`L2 cache <l2-cache>`. These are broken down by the operation type
(read / write / atomic, with, or without return), and the
:ref:`memory type <memory-type>`.
.. _desc-td:
Vector L1 data-return path or Texture Data (TD)
===============================================
The data-return path of the vL1D cache, also known as the Texture Data
(TD) unit, is responsible for routing data returned from the
:ref:`vL1D cache RAM <desc-tc>` back to a wavefront on a SIMD. As described in
the :ref:`vL1D cache front-end <desc-ta>` section, the data-return path is passed
information about the space requirements and routing for data requests
from the :ref:`VALU <desc-valu>`. When data is returned from the
:ref:`vL1D cache RAM <desc-tc>`, it is matched to this previously stored request
data, and returned to the appropriate SIMD.
Omniperf reports the following vL1D data-return path metrics:
.. list-table::
:header-rows: 1
* - Metric
- Description
- Unit
* - Data-return Busy
- Percent of the :ref:`total CU cycles <total-cu-cycles>` the data-return
unit was busy processing or waiting on data to return to the
:doc:`CU <compute-unit>`.
- Percent
* - Cache RAM → Data-return Stall
- Percent of the :ref:`total CU cycles <total-cu-cycles>` the data-return
unit was stalled on data to be returned from the
:ref:`vL1D Cache RAM <desc-tc>`.
- Percent
* - Workgroup manager → Data-return Stall
- Percent of the :ref:`total CU cycles <total-cu-cycles>` the data-return
unit was stalled by the :ref:`workgroup manager <desc-spi>` due to
initialization of registers as a part of launching new workgroups.
- Percent
* - Coalescable Instructions
- The number of instructions submitted to the
:ref:`data-return unit <desc-td>` by the
:ref:`address processor <desc-ta>` that were found to be coalescable, per
:ref:`normalization unit <normalization-units>`.
- Instructions per :ref:`normalization unit <normalization-units>`
* - Read Instructions
- The number of read instructions submitted to the
:ref:`data-return unit <desc-td>` by the
:ref:`address processor <desc-ta>` summed over all
:doc:`compute units <compute-unit>` on the accelerator, per
:ref:`normalization unit <normalization-units>`. This is expected to be
the sum of global/generic and spill/stack reads in the
:ref:`address processor <desc-ta>`.
- Instructions per :ref:`normalization unit <normalization-units>`
* - Write Instructions
- The number of store instructions submitted to the
:ref:`data-return unit <desc-td>` by the
:ref:`address processor <desc-ta>` summed over all
:doc:`compute units <compute-unit>` on the accelerator, per
:ref:`normalization unit <normalization-units>`. This is expected to be
the sum of global/generic and spill/stack stores counted by the
:ref:`vL1D cache-front-end <ta-instruction-counts>`.
- Instructions per :ref:`normalization unit <normalization-units>`
* - Atomic Instructions
- The number of atomic instructions submitted to the
:ref:`data-return unit <desc-td>` by the
:ref:`address processor <desc-ta>` summed over all
:doc:`compute units <compute-unit>` on the accelerator, per
:ref:`normalization unit <normalization-units>`. This is expected to be
the sum of global/generic and spill/stack atomics in the
:ref:`address processor <desc-ta>`.
- Instructions per :ref:`normalization unit <normalization-units>`