Hyppää sisältöön

Docs CSC now features an automatic Finnish translation. Click here for more information.

Warning!

Puhti and Mahti are being decommissioned in stages, and their storage areas will become fully unavailable from 15 October 2026. Clean up unnecessary files and move any data you need to keep by 31 August 2026. See the Roihu data migration guide for instructions on transferring your data to Roihu.

Puhti scratch is very full: keep only active data there and move or delete everything else. No new Puhti scratch quota will be granted.

CPU-affiniteetin tarkastelu ja hallinta

Tässä oppaassa kuvataan, miten CPU-affiniteetteja voidaan tarkastella ja hallita työskripteissä CSC:n supertietokoneilla. Oppaan skriptit on kirjoitettu Roihu-supertietokoneelle, mutta ne soveltuvat yleisesti myös Puhdissa, Mahdissa ja LUMI:ssa.

Mitä CPU-affiniteetti on?

CPU-affiniteetti kuvaa, miten käynnissä oleva ohjelma sijoitetaan supertietokonesolmun käytettävissä oleville CPU-ytimille. Affiniteettia hallitsemalla päätämme, millä CPU-ytimillä ohjelma saa suorittua, eli rajoitamme tai kiinnitämme sen sijoittelun sen sijaan, että jättäisimme sen kokonaan järjestelmän päätettäväksi.

Suurteholaskennassa affiniteetin oikea asettaminen on tärkeää suorituskyvyn kannalta. Se auttaa ohjelmia hyödyntämään paremmin prosessorin nopeita välimuisteja ja muistia, vähentää tarpeetonta siirtymistä ytimien välillä ja johtaa vakaampiin ja ennustettavampiin ajoaikoihin.

CPU-affiniteetin tarkastelu Slurm-töissä

Seuraavaa esimerkkityöskriptiä voidaan käyttää kunkin Slurm-tehtävän CPU-affiniteettien tarkistamiseen. Työskripti suorittaa csc-print-affinity-komennon (csc-tools-moduulissa saatavilla) srun-komennolla:

#!/bin/bash
#SBATCH --job-name=example
#SBATCH --account=<project>
#SBATCH --partition=medium
#SBATCH --time=00:30:00
#SBATCH --nodes=2
#SBATCH --ntasks-per-node=8 --cpus-per-task=48  # The product should be 384

# Run the program
srun csc-print-affinity

Esimerkkituloste tälle työlle:

Task   10 running on node rc6284 core 96-143
Task   11 running on node rc6284 core 144-191
Task    9 running on node rc6284 core 48-95
Task   15 running on node rc6284 core 336-383
Task   12 running on node rc6284 core 192-239
Task   13 running on node rc6284 core 240-287
Task   14 running on node rc6284 core 288-335
Task    8 running on node rc6284 core 0-47
Task    7 running on node rc6283 core 336-383
Task    1 running on node rc6283 core 48-95
Task    3 running on node rc6283 core 144-191
Task    6 running on node rc6283 core 288-335
Task    4 running on node rc6283 core 192-239
Task    2 running on node rc6283 core 96-143
Task    5 running on node rc6283 core 240-287
Task    0 running on node rc6283 core 0-47

Tämä tuloste osoittaa, että CSC:n supertietokoneet on oletusarvoisesti määritetty siten, että jokaiselle Slurm-tehtävälle varataan oma yksinomainen CPU-ydinjoukkonsa allokaatiosta. Tehtävää kohti varattujen ytimien määrä määräytyy Slurm-valinnan cpus-per-task perusteella.

Edistynyt aihe: CPU-affiniteetin manuaalinen hallinta Slurm-töissä

Edistynyt aihe

Tässä osiossa kuvataan CPU-affiniteetin edistynyttä manuaalista hallintaa. Käytännössä tätä tarvitaan harvoin, ja Slurmin oletusmääritys on paras useimmille kuormille. Jos uskot tarvitsevasi manuaalista CPU-sidontaa, ota ensin yhteyttä meihin saadaksesi ohjeita.

Jos tarvitaan erilainen sijoittelustrategia, oletusarvoinen CPU-sidonta voidaan poistaa käytöstä valinnalla srun --cpu-bind=none. Tämä poistaa kaikki CPU-affiniteettirajoitukset ja sallii prosessien suorittua milllä tahansa solmun varatuista ytimistä. Tämä on yleensä epätoivottavaa suorituskyvyn kannalta, ellei sitä yhdistetä eksplisiittiseen manuaaliseen sidontaan, joka voidaan tehdä esimerkiksi numactl-työkalulla.

Seuraava työskripti antaa esimerkin CPU-sidonnan asettamisesta manuaalisesti. Työskripti luo skriptin cpu_bind.<jobid>.sh, joka käyttää numactl-työkalua tehtävien sitomiseen CPU-ytimiin samalla tavalla kuin oletusarvoisesti: kullekin tehtävälle annetaan yhtenäinen CPU-ydinlohko tehtävän paikallisen tunnisteen ja tehtävää kohti varattujen CPU:iden määrän perusteella:

Skripti kokonaisille solmuille

Tämä skripti toimii oikein vain kokonaisilla solmuilla.

#!/bin/bash
#SBATCH --job-name=example
#SBATCH --account=<project>
#SBATCH --partition=medium
#SBATCH --time=00:30:00
#SBATCH --nodes=2
#SBATCH --ntasks-per-node=8 --cpus-per-task=48  # The product should be 384

# Create a script for binding tasks to CPU cores
BIND_CPU="./bind_cpu.$SLURM_JOB_ID.sh"
cat << 'EOF' > $BIND_CPU
#!/bin/bash
cpus_per_task=${SLURM_CPUS_PER_TASK:-1}
start_core=$((SLURM_LOCALID * cpus_per_task))
end_core=$((SLURM_LOCALID * cpus_per_task + cpus_per_task - 1))
numactl --physcpubind ${start_core}-${end_core} "$@"
EOF
chmod +x $BIND_CPU

# Remove the script on exit
trap "rm -f $BIND_CPU" EXIT

# Run the program with manual binding
srun --cpu-bind=none $BIND_CPU csc-print-affinity

Tämä tuottaa yllä näkyvää oletusarvoista CPU-sidontaa vastaavan tulosteen, mikä vahvistaa, että manuaalinen sijoittelu toistaa vakiokäyttäytymisen:

Task    4 running on node rc6283 core 192-239
Task    6 running on node rc6283 core 288-335
Task    7 running on node rc6283 core 336-383
Task    5 running on node rc6283 core 240-287
Task    0 running on node rc6283 core 0-47
Task    1 running on node rc6283 core 48-95
Task    2 running on node rc6283 core 96-143
Task    3 running on node rc6283 core 144-191
Task   15 running on node rc6284 core 336-383
Task    8 running on node rc6284 core 0-47
Task    9 running on node rc6284 core 48-95
Task   10 running on node rc6284 core 96-143
Task   11 running on node rc6284 core 144-191
Task   12 running on node rc6284 core 192-239
Task   13 running on node rc6284 core 240-287
Task   14 running on node rc6284 core 288-335

Tarvittaessa sidontaskriptin logiikkaa voidaan muokata sitomaan CPU-ytimet sovelluksesi tarpeiden mukaisesti.

MPI+OpenMP-sovellusten CPU-affiniteetin tarkastelu ja hallinta

Monet HPC-sovellukset hyötyvät OpenMP-säikeiden sitomisesta CPU-ytimiin. Tämä ei tapahdu automaattisesti, vaan se täytyy ottaa käyttöön seuraavilla riveillä erätyöskriptissä:

# Place and bind threads to single cores
export OMP_PLACES=cores
export OMP_PROC_BIND=spread

Tämä opas havainnollistaa näiden asetusten merkitystä.

Tarkastellaan ensin oletuskäyttäytymistä tilanteessa, jossa säikeitä ei ole sidottu. Seuraava työskripti havainnollistaa OMP_*-muuttujien käyttöä kunkin prosessin ja OpenMP-säikeen CPU-affiniteettien tarkistamiseen:

#!/bin/bash
#SBATCH --job-name=example
#SBATCH --account=<project>
#SBATCH --partition=small
#SBATCH --time=00:30:00
#SBATCH --nodes=1
#SBATCH --ntasks=2
#SBATCH --cpus-per-task=8
#SBATCH --mem-per-cpu=1000M

# Set the number of threads based on cpus-per-task
export OMP_NUM_THREADS=${SLURM_CPUS_PER_TASK:-1}

# Print thread affinities
export OMP_DISPLAY_AFFINITY=true
export OMP_AFFINITY_FORMAT="Process %P level %L thread %0.4n/%0.4N on node %H core %A"

# Run the program
srun <my_openmp_program>

Esimerkkituloste tälle työlle:

Process 2808761 level 1 thread 0000/0004 on node rc6224 core 0-3
Process 2808761 level 1 thread 0001/0004 on node rc6224 core 0-3
Process 2808761 level 1 thread 0002/0004 on node rc6224 core 0-3
Process 2808761 level 1 thread 0003/0004 on node rc6224 core 0-3
Process 2808762 level 1 thread 0000/0004 on node rc6224 core 4-7
Process 2808762 level 1 thread 0001/0004 on node rc6224 core 4-7
Process 2808762 level 1 thread 0002/0004 on node rc6224 core 4-7
Process 2808762 level 1 thread 0003/0004 on node rc6224 core 4-7

Tämä tuloste tarkoittaa, että prosessien säikeet voivat liikkua vapaasti neljän ytimen joukkojen välillä (0–3 tai 4–7), mikä voi heikentää suorituskykyä lisääntyneen kontekstinvaihdon ja säikeiden siirtymisen vuoksi ajon aikana verrattuna tilanteeseen, jossa säikeet on sidottu yksittäisiin ytimiin.

Seuraavassa esimerkkityöskriptissä säikeiden sidonta on otettu käyttöön:

#!/bin/bash
#SBATCH --job-name=example
#SBATCH --account=<project>
#SBATCH --partition=small
#SBATCH --time=00:30:00
#SBATCH --nodes=1
#SBATCH --ntasks=2
#SBATCH --cpus-per-task=8
#SBATCH --mem-per-cpu=1000M

# Set the number of threads based on cpus-per-task
export OMP_NUM_THREADS=${SLURM_CPUS_PER_TASK:-1}

# Place and bind threads to single cores
export OMP_PLACES=cores
export OMP_PROC_BIND=spread

# Print thread affinities
export OMP_DISPLAY_AFFINITY=true
export OMP_AFFINITY_FORMAT="Process %P level %L thread %0.4n/%0.4N on node %H core %A"

# Run the program
srun <my_openmp_program>

Nyt tuloste näyttää tältä:

Process 2808761 level 1 thread 0000/0004 on node rc6224 core 0
Process 2808761 level 1 thread 0001/0004 on node rc6224 core 1
Process 2808761 level 1 thread 0002/0004 on node rc6224 core 2
Process 2808761 level 1 thread 0003/0004 on node rc6224 core 3
Process 2808762 level 1 thread 0000/0004 on node rc6224 core 4
Process 2808762 level 1 thread 0001/0004 on node rc6224 core 5
Process 2808762 level 1 thread 0002/0004 on node rc6224 core 6
Process 2808762 level 1 thread 0003/0004 on node rc6224 core 7

Tämä tuloste tarkoittaa, että jokainen säie on sidottu omaan ytimeensä, mikä on usein toivottavaa parhaan suorituskyvyn saavuttamiseksi.

Yleisesti ottaen, kun alat käyttää uutta sovellusta tai kokoonpanoa, on olennaista käyttää näitä asetuksia säikeiden sijoittelun varmistamiseen ja sen tarkistamiseen, että affiniteetti toteutuu odotetusti. Tämä on usein keskeinen vaihe suorituskyvyn diagnosoinnissa tai optimoinnissa supertietokoneella.

Jos tuloste esimerkiksi näyttäisi, että useita prosesseja tai säikeitä on sidottu samaan ytimeen samalla solmulla,

Process 2808761 level 1 thread 0000/0004 on node rc6224 core 0
Process 2808761 level 1 thread 0001/0004 on node rc6224 core 1
Process 2808761 level 1 thread 0002/0004 on node rc6224 core 2
Process 2808761 level 1 thread 0003/0004 on node rc6224 core 3
Process 2808762 level 1 thread 0000/0004 on node rc6224 core 0
Process 2808762 level 1 thread 0001/0004 on node rc6224 core 1
Process 2808762 level 1 thread 0002/0004 on node rc6224 core 2
Process 2808762 level 1 thread 0003/0004 on node rc6224 core 3
tai
Process 2808761 level 1 thread 0000/0004 on node rc6224 core 0
Process 2808761 level 1 thread 0001/0004 on node rc6224 core 0
Process 2808761 level 1 thread 0002/0004 on node rc6224 core 0
Process 2808761 level 1 thread 0003/0004 on node rc6224 core 0
Process 2808762 level 1 thread 0000/0004 on node rc6224 core 0
Process 2808762 level 1 thread 0001/0004 on node rc6224 core 0
Process 2808762 level 1 thread 0002/0004 on node rc6224 core 0
Process 2808762 level 1 thread 0003/0004 on node rc6224 core 0
tai jotain vastaavaa, suorituskyky on todennäköisesti heikentynyt ja erätyöskriptin asetukset tulisi korjata.

Älä epäröi ottaa yhteyttä meihin, jos tarvitset apua sovelluksesi hyvän suorituskyvyn varmistamisessa.

Lisätietoja

Suomenkielinen tekoälykäännös

Sisällössä voi esiintyä virheellistä tietoa tekoälykäännöksestä johtuen.

Klikkaa tästä antaaksesi palautetta