Compartir a través de


Ejecución de la primera prueba comparativa mediante STREAM

STREAM mide el ancho de banda de memoria sostenible, que es fundamental para cargas de trabajo enlazadas a memoria, como dinámica de fluidos computacionales (CFD), análisis de elementos finitos y análisis de datos. STREAM es una prueba comparativa sintética sencilla que mide el ancho de banda de memoria para cuatro operaciones vectoriales:

Operación Description Formula
Copiar Mide las velocidades de transferencia a(i) = b(i)
Escalabilidad Agrega aritmética simple a(i) = q × b(i)
Añadir Varias operaciones de carga y almacenamiento a(i) = b(i) + c(i)
Tríada Más representativo a(i) = b(i) + q × c(i)

El resultado de triad es la métrica estándar para comparar el ancho de banda de memoria entre sistemas.

Tiempo de finalización: 15-20 minutos

Prerrequisitos

  • Una máquina virtual de Azure HPC (HBv3, HBv4, HBv5 o la serie HX recomendada)
  • Acceso SSH a la máquina virtual
  • Privilegios raíz o sudo

Sugerencia

Para obtener los mejores resultados, use imágenes de Marketplace de Azure HPC (AlmaLinux-HPC o Ubuntu-HPC) que incluyen compiladores y bibliotecas optimizados.

Resultados esperados por familia de máquinas virtuales

Use estos valores para validar los resultados:

Serie de máquinas virtuales STREAM Triad (GB/s) Notas
HBv5 (con HBM) ~7.000 Usa memoria HBM
HBv4 ~650-780 Memoria DDR5
HBv3 ~330-350 Memoria DDR4
HBv2 ~260 Memoria DDR4

Si los resultados son significativamente inferiores (más de 10% a continuación), compruebe la configuración.

Paso 1: Conexión a la máquina virtual

Conéctese mediante SSH a la máquina virtual de HPC:

ssh azureuser@<vm-public-ip>

O bien, conéctese a través del nodo de inicio de sesión de Slurm si usa un clúster.

Paso 2: Instalación de dependencias

Las imágenes de Azure HPC incluyen los compiladores necesarios. Compruebe que GCC está disponible:

gcc --version

Opción B: Instalación manual

Si usa una imagen estándar, instale las herramientas de compilación:

# AlmaLinux/RHEL
sudo dnf groupinstall "Development Tools" -y

# Ubuntu
sudo apt update && sudo apt install build-essential -y

Paso 3: Descargar y compilar STREAM

Clone el repositorio de pruebas comparativas de Azure que incluye configuraciones de STREAM optimizadas:

# Create working directory
mkdir -p ~/benchmarks && cd ~/benchmarks

# Clone Azure benchmarking repository
git clone https://github.com/Azure/woc-benchmarking.git
cd woc-benchmarking/apps/hpc/stream

Como alternativa, descargue STREAM directamente:

mkdir -p ~/benchmarks/stream && cd ~/benchmarks/stream
wget https://www.cs.virginia.edu/stream/FTP/Code/stream.c

Compile con optimizaciones para procesadores AMD EPYC (usados en la serie HB):

gcc -O3 -march=znver3 -fopenmp -DSTREAM_ARRAY_SIZE=800000000 \
    -DNTIMES=20 stream.c -o stream

Se explican las marcas del compilador:

Flag Propósito
-O3 Nivel máximo de optimización
-march=znver3 Optimización para la arquitectura AMD Zen 3/4
-fopenmp Habilitación de OpenMP para el multithreading
-DSTREAM_ARRAY_SIZE=800000000 Tamaño de matriz (~6 GB por matriz, 18 GB en total)
-DNTIMES=20 Número de iteraciones

Importante

El tamaño de la matriz debe ser lo suficientemente grande como para que los datos no quepan en la memoria caché. Para HBv4/HBv5 con caché L3 de 1,5 GB, use al menos 800M elementos.

Paso 4: Configurar la afinidad del hilo

El anclaje adecuado de subprocesos es fundamental para obtener resultados precisos. Establezca variables de entorno de OpenMP:

# Get number of physical cores
NCORES=$(lscpu | grep "^Core(s) per socket:" | awk '{print $4}')
NSOCKETS=$(lscpu | grep "^Socket(s):" | awk '{print $2}')
TOTAL_CORES=$((NCORES * NSOCKETS))

echo "Total physical cores: $TOTAL_CORES"

# Set OpenMP configuration
export OMP_NUM_THREADS=$TOTAL_CORES
export OMP_PROC_BIND=spread
export OMP_PLACES=cores

Para HBv4 (176 núcleos):

export OMP_NUM_THREADS=176
export OMP_PROC_BIND=spread
export OMP_PLACES=cores

Para HBv5 (configuración estándar):

export OMP_NUM_THREADS=176
export OMP_PROC_BIND=spread
export OMP_PLACES=cores

Paso 5: Ejecutar el banco de pruebas

Ejecutar STREAM:

./stream

Salida de ejemplo (HBv4):

-------------------------------------------------------------
STREAM version $Revision: 5.10 $
-------------------------------------------------------------
This system uses 8 bytes per array element.
-------------------------------------------------------------
Array size = 800000000 (elements), Offset = 0 (elements)
Memory per array = 6103.5 MiB (= 5.96 GiB).
Total memory required = 18310.5 MiB (= 17.88 GiB).
Each kernel will be executed 20 times.
-------------------------------------------------------------
Number of Threads requested = 176
Number of Threads counted = 176
-------------------------------------------------------------
Function    Best Rate MB/s  Avg time     Min time     Max time
Copy:          753284.2     0.017157     0.016966     0.018884
Scale:         707935.3     0.018260     0.018045     0.019629
Add:           756972.9     0.025508     0.025318     0.027311
Triad:         757820.9     0.025464     0.025290     0.027212
-------------------------------------------------------------

El Triad Best Rate (757.820,9 MB/s = ~740 GB/s) es el resultado clave.

Paso 6: Validar los resultados

Compare el resultado de la triad con los valores esperados:

# Quick validation script
TRIAD_RESULT=757820  # Replace with your result in MB/s
VM_TYPE="HBv4"       # HBv2, HBv3, HBv4, or HBv5

case $VM_TYPE in
    "HBv5") EXPECTED=7000000 ;;
    "HBv4") EXPECTED=700000 ;;
    "HBv3") EXPECTED=330000 ;;
    "HBv2") EXPECTED=260000 ;;
esac

PERCENT=$(echo "scale=1; $TRIAD_RESULT * 100 / $EXPECTED" | bc)
echo "Achieved $PERCENT% of expected bandwidth"

Interpretación de los resultados:

Logro Interpretación
95-105% Excelente: máquina virtual que funciona según lo previsto
85-95% Bueno: optimización menor posible
70-85% Investigación: verificación de la afinidad de subprocesos, NUMA
<70% Problema: comprobación de la configuración

Paso 7: Ejecutar en varios dominios NUMA (avanzados)

Para obtener un análisis detallado de NUMA, ejecute STREAM por dominio NUMA:

# Check NUMA topology
numactl --hardware

# Run on NUMA node 0 only
numactl --cpunodebind=0 --membind=0 \
    OMP_NUM_THREADS=22 OMP_PROC_BIND=spread OMP_PLACES=cores ./stream

# Run on all NUMA domains (default full-node run)
numactl --interleave=all \
    OMP_NUM_THREADS=176 OMP_PROC_BIND=spread OMP_PLACES=cores ./stream

Solución de problemas

Resultados de baja ancho de banda

Síntoma: resultados significativamente inferiores a los valores esperados

Soluciones:

  1. Comprobar el conteo de hilos:

    echo $OMP_NUM_THREADS
    # Should match physical core count
    
  2. Comprobación del enlace de subprocesos:

    export OMP_DISPLAY_ENV=TRUE
    ./stream 2>&1 | head -20
    
  3. Compruebe el escalado de frecuencia de CPU:

    cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
    # Should be "performance" for benchmarking
    
  4. Compruebe la directiva de memoria NUMA:

    numactl --show
    

Tamaño de matriz demasiado pequeño

Síntoma: resultados mayores de lo esperado (medición de la memoria caché, no memoria)

Solución: aumente STREAM_ARRAY_SIZE en tiempo de compilación. La memoria total usada debe ser al menos 4× el tamaño de caché L3.

# Recompile with larger array
gcc -O3 -march=znver3 -fopenmp -DSTREAM_ARRAY_SIZE=1000000000 \
    -DNTIMES=20 stream.c -o stream

Resultados incoherentes

Síntoma: Gran variación entre ejecuciones

Soluciones:

  1. Asegúrese de que no se están ejecutando otros procesos:

    top -b -n 1 | head -20
    
  2. Ejecute más iteraciones:

    # Recompile with more iterations
    gcc -O3 -march=znver3 -fopenmp -DSTREAM_ARRAY_SIZE=800000000 \
        -DNTIMES=50 stream.c -o stream
    

Ejecución de STREAM en un trabajo de Slurm

Si usa un clúster de Slurm, cree un script de trabajo:

cat << 'EOF' > stream-job.sh
#!/bin/bash
#SBATCH --job-name=stream
#SBATCH --nodes=1
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=176
#SBATCH --time=00:10:00
#SBATCH --partition=hpc
#SBATCH --exclusive

# Set thread configuration
export OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK
export OMP_PROC_BIND=spread
export OMP_PLACES=cores

# Run STREAM
cd ~/benchmarks/woc-benchmarking/apps/hpc/stream
./stream
EOF

sbatch stream-job.sh

Automatización con los scripts de pruebas comparativas de Azure

El repositorio de Azure woc-benchmarking incluye scripts de automatización.

cd ~/benchmarks/woc-benchmarking/apps/hpc/stream

# View available scripts
ls -la

# Run automated benchmark (if available)
./run_stream.sh