Barra : un simulateur de GPU pour CUDA
Sylvain Collange
(sylvain.collange@univ-perp.fr)
Qu’est-ce qu’un simulateur ?
Les simulateurs fonctionnels émulent le comportement d’un processeur,
indépendants de l’implémentation, ou micro-architecture. Ils permettent de :
– concevoir et tester des jeux d’instructions,
– générer des traces d’exécution,
–tester et le déboguer des logiciels.
Les simulateurs niveau transaction et niveau cycle simulent une micro-
architecture donnée suivant un modèle de temps, voire de consommation. Ils
permettent :
– d’instrumenter et d’optimiser les logiciels,
– d’identifier les goulets d’étranglement d’une micro-architecture,
– de quantifier l’impact de modifications micro-architecturales,
– de borner des temps d’exécution (WCET). . .
Simulateurs existants
– CPU : SimpleScalar, ooosim. . .
– GPU : Attila, Qsilver.
Un GPU : NVIDIA G80
Spécificités
–SIMD large,
–multithreading matériel massif,
– exécution transparente des branchements par prédication,
– accès mémoire par Gather et Scatter,
– mémoire hétégogène : constante, locale, globale. . .
Ces aspects ne sont pas pris en charge par les simulateurs existants.
L’architecture n’est pas documentée en détail. Il est nécessaire d’effectuer
des tests pour en comprendre le fonctionnement [1, 4]. Nous nous intéres-
sons à l’architecture NVIDIA :G80, G92 et GT200 et à son jeu d’instruction
[5].
031
Mot 0
OP
Adress reg[0-1]
Adress Imm/reg
Src3 from const mem
Src2 from const mem
Src2
Src1
Dest
Flow control
Long instruction
31
Mot 1
SubOP
Src3 neg
Src1 neg
Src2 imm
Rounding mode
Src1 from sh mem
Src3
Pred reg
Pred cond
Set pred
Set pred reg
Dest is output reg
Marker
Adress reg[2]
16
16
24 8
024 8
Simuler le G80
Un émulateur du jeu d’instruction NVIDIA G80 décode et exécute les instruc-
tions natives.
0xe422c78004001801 mov.b32 s[a1+0x0030], r11
0xe420078004003801 mov.b32 s[a1+0x0070], r0
0x00000000861ffe03 bar.sync 0
0x0423c7801c00c001 mov.u32.u32.rd r0, s[a3+0x0000] r0 = (0.794227, 0.115912, . . .)
0x00208780e800d809 mad.f32.rn r2, s[a2+0x0030], r0, r2 r2 = (0.309071, 0.045107, . . .)
0x0423c7801c00c801 mov.u32.u32.rd r0, s[a3+0x0010] r0 = (0.157347, 0.436301, . . .)
Les registres et les opérateurs sont vectoriels. Les branchements sont simu-
lés par prédication implicite à l’aide d’une pile de masque et de plusieurs piles
d’adresses.
if(p)
{
...
}
else
{
...
}
@!p br else
...
br endif
else:
...
endif:
Code C Assembleur Pile masquesPile cibles
else
endif
push(else)
push(endif)
push(p)
p= pop()
push(¯p∧top)
pop() pop()
PC = pop()
Le simulateur exécute alternativement les instructions de plusieurs threads
(warps) suivant un ordonnancement round-robin. Ces warps sont synchroni-
sables par une instruction barrière. Les instructions d’accès mémoire Gather
et Scatter acceptent des vecteurs d’adresses.
Les bancs de registres sont implicitement indexés par le numéro de warp
courant. Les instructions sont prédiquées à la fois de manière explicite par un
registre de prédicat et de manière implicite par le masque de branchement
courant.
Les instructions sont complexes mais décomposables en sous-éléments or-
thogonaux : prédicat, opération, destination, sources. Chaque sous-élément
est décodé indépendamment.
M´
emoire
Warp 3 : @p1.leu mad.f32.rn p1|r2, s[a2+48], r0, c14[32]
PC
Ordon-
nanceur
Registres g´
en´
eraux
Registres
adresse
Registres
pr´
edicat
Masque
D´
ecodeurs
Num´
ero
de warp
ALU/
FPU
Ordonnancement Fetch D´
ecodage Lecture op´
erandes Ex´
ecution ´
Ecriture
64
32
32x32
32x32
32x32
4x32
32x32
Warp 3
mad.f32.rn
r0
a2
@p1
.leu
r2
32
c14[32]
s[a2+48]
ID de warp
Vecteur
Addresse
Masque
p1
4x32
mad.f32.rn
s[a2+48]
c14[32]
@p1.leu
p1|r2
r0
Pred
OP
Dest
Src1
Src2
Src3
masque &
W1
W2
W3
W4
W24
@p1.leu
Intégration avec CUDA
Un pilote virtuel sous la forme d’une bibliothèque dynamique remplace la bi-
bliothèque NVIDIA CUDA et intercepte les appels de fonctions de l’application
ou de la couche Runtime haut-niveau de CUDA. Aucune recompilation n’est
nécessaire. Des drapeaux permettent d’activer la génération de traces.
CUDA Runtime
Application
Pilote CUDA
GPU
CUDA Runtime
Application
Pilote Barra
Simulateur de GPU
Résultats
– Simulation correcte de la plupart des programmes du SDK CUDA.
– Vitesse d’exécution comparable à celle de l’émulation niveau source.
GPU execution (9800GX2)
Barra
CUDA emulation
0
1
10
100
1,000
10,000
100,000
MersenneTwister
MersenneTwisterBM
MonteCarlo
fastWalshTransform
histogram256
matrixMul
reduction
scanLargeArray
transpose
Execution time
Travaux futurs
– Validation de propositions de modifications architecturales [2].
– Simulation niveau transaction de la mémoire et des cœurs d’exécution.
– Modèle de consommation.
– Débogueur.
Références
[1] Sylvain Collange, Marc Daumas, and David Defour. État de l’intégration de la virgule
flottante dans les processeurs graphiques. RSTI-TSI, VOL 27/6:719–733, 2008.
[2] Sylvain Collange, Marc Daumas, David Defour, and Régis Olivès. Fonctions élémentaires
sur GPU exploitant la localité de valeurs. In Actes de SYMPA, 2008. http://hal.archives-
ouvertes.fr/hal-00202906.
[3] Sylvain Collange, David Defour, and David Parello. Barra, a Modular Functional GPU
Simulator for GPGPU. http://hal.archives-ouvertes.fr/hal-00359342, 2009.
[4] Sylvain Collange, David Defour, and Arnaud Tisserand. Power Consuption of GPUs from
a Software Perspective. http://hal.archives-ouvertes.fr/hal-00348672, 2009.
[5] Wladimir J. van der Laan. Decuda, cudasm, 2007. http://www.cs.rug.nl/~wladimir/decuda/.