Hyper-Q / MPS
Aperçu
Hyper-Q (ou MPS pour Multi-Process Service) est une fonctionnalité des GPU de NVIDIA qui sont compatibles avec les versions 3.5 et plus récentes de CUDA [1] ce qui est le cas pour toutes nos grappes d'usage général (Béluga, Cedar, Graham et Narval).
Selon la documentation de NVIDIA,
- [traduction libre]L'architecture d'exécution MPS est conçue pour permettre de façon transparente l'utilisation d'applications CUDA parallèles et coopératives (comme le sont typiquement les tâches MPI) en tirant avantage des fonctionnalités Hyper-Q des derniers GPU de NVIDIA (Kepler et suivants). Hyper-Q permet aux noyaux CUDA d’être traités en simultané sur un même GPU, ce qui améliore la performance quand la capacité de calcul du GPU est sous-utilisée par un seul processus.
Nos tests ont démontré que MPS peut augmenter le nombre d'opérations en virgule flottante effectuées par seconde (flops) même quand le GPU est partagé entre des processus CPU qui ne sont pas reliés. Ceci signifie que MPS est la fonctionnalité idéale pour des applications CUDA qui traitent des problèmes dont leur taille relativement petite les rend incapables de bien occuper les GPU modernes dotés de milliers de cœurs.
MPS n'est pas activée par défaut, mais il suffit de lancer les commandes suivantes avant de démarrer votre application CUDA.
[name@server ~]$ export CUDA_MPS_PIPE_DIRECTORY=/tmp/nvidia-mps
[name@server ~]$ export CUDA_MPS_LOG_DIRECTORY=/tmp/nvidia-log
[name@server ~]$ nvidia-cuda-mps-control -d
Vous pouvez alors utiliser MPS si vous avez plus d'un fil CPU qui a accès au GPU. Ceci se produit quand vous exécutez une application hybride MPI/CUDA, une application hybride OpenMP/CUDA ou plusieurs applications séquentielles CUDA (GPU farming).
Pour plus d'information sur MPS, voir la documentation de NVIDIA.
Farming avec GPU
La fonctionnalité MPS est très utile pour exécuter plusieurs instances d’une même application CUDA quand celle-ci est trop petite pour occuper entièrement un GPU moderne. MPS vous permet d’exécuter toutes ces instances, pourvu que la mémoire du GPU soit suffisante. Dans plusieurs cas, la production de résultats pourrait être grandement augmentée.
Le script suivant est un exemple pour configurer le farming avec GPU.
#!/bin/bash
#SBATCH --gpus-per-node=v100:1
#SBATCH --time=0-10:00
#SBATCH --mem-per-cpu=8G
#SBATCH --cpus-per-task=8
mkdir -p $HOME/tmp
export CUDA_MPS_LOG_DIRECTORY=$HOME/tmp
nvidia-cuda-mps-control -d
for ((i=0; i<8; i++))
do
echo $i
./my_code $i &
done
wait
In the above example, we share a single V100 GPU between 8 instances of my_code
(which takes a single argument-- the loop index $i). We request 8 CPU cores (#SBATCH -c 8) so there is one CPU core per application instance. The two important elements are
&
on the code execution line, which sends the code processes to the background, and- the
wait
command at the end of the script, which ensures that the job runs until all background processes end.
- ↑ Voir le tableau des modèles, architectures et capacités de calcul CUDA dans https://en.wikipedia.org/wiki/Nvidia_Tesla.