Compiler optimisations and relaxed memory consistency models / Robin Morisset ; sous la direction de Francesco Zappa Nardelli

Date :

Type : Livre / Book

Type : Thèse / Thesis

Langue / Language : anglais / English

Informatique

Compilateurs (logiciels)

Classification Dewey : 004

Zappa Nardelli, Francesco (1976-....) (Directeur de thèse / thesis advisor)

Pouzet, Marc (Président du jury de soutenance / praeses)

Lea, Douglas (Rapporteur de la thèse / thesis reporter)

Appel, Andrew W. (1960-....) (Rapporteur de la thèse / thesis reporter)

Dreyer, Derek (1980-....) (Membre du jury / opponent)

Vyukov, Dmitry (Membre du jury / opponent)

Batty, Mark (Membre du jury / opponent)

Université de Recherche Paris Sciences et Lettres (Organisme de soutenance / degree-grantor)

École doctorale Sciences mathématiques de Paris centre (Paris ; 2000-....) (Ecole doctorale associée à la thèse / doctoral school)

École normale supérieure (Paris ; 1985-....). Département d'informatique (Laboratoire associé à la thèse / thesis associated laboratory)

École normale supérieure (Paris ; 1985-....) (Autre partenaire associé à la thèse / thesis associated third party)

Équipe de recherche Parallélisme de Kahn synchrone (Paris) (Laboratoire associé à la thèse / thesis associated laboratory)

Résumé / Abstract : Les architectures modernes avec des processeurs multicœurs, ainsi que les langages de programmation modernes, ont des mémoires faiblement consistantes. Leur comportement est formalisé par le modèle mémoire de l'architecture ou du langage de programmation ; il définit précisément quelle valeur peut être lue par chaque lecture dans la mémoire partagée. Ce n'est pas toujours celle écrite par la dernière écriture dans la même variable, à cause d'optimisation dans les processeurs, telle que l'exécution spéculative d'instructions, des effets complexes des caches, et des optimisations dans les compilateurs. Dans cette thèse, nous nous concentrons sur le modèle mémoire C11 qui est défini par l'édition 2011 du standard C. Nos contributions suivent trois axes. Tout d'abord, nous avons regardé la théorie autour du modèle C11, étudiant de façon formelle quelles optimisations il autorise les compilateurs à faire. Nous montrons que de nombreuses optimisations courantes sont permises, mais, surprenamment, d'autres, importantes, sont interdites. Dans un second temps, nous avons développé une méthode à base de tests aléatoires pour détecter quand des compilateurs largement utilisés tels que GCC et Clang réalisent des optimisations invalides dans le modèle mémoire C11. Nous avons trouvés plusieurs bugs dans GCC, qui furent tous rapidement fixés. Nous avons aussi implémenté une nouvelle passez d'optimisation dans LLVM, qui recherchent des instructions des instructions spéciales qui limitent les optimisations faites par le processeur - appelées instructions barrières - et élimine celles qui ne sont pas utiles. Finalement, nous avons développé un ordonnanceur en mode utilisateur pour des threads légers communicants via des canaux premier entré-premier sorti à un seul producteur et un seul consommateur. Ce modèle de programmation est connu sous le nom de réseau de Kahn, et nous montrons comment l'implémenter efficacement, via les primitives désynchronisation de C11. Ceci démontre qu'en dépit de ses problèmes, C11 peut être utilisé en pratique.

Résumé / Abstract : Modern multiprocessors architectures and programming languages exhibit weakly consistent memories. Their behaviour is formalised by the memory model of the architecture or programming language; it precisely defines which write operation can be returned by each shared memory read. This is not always the latest store to the same variable, because of optimisations in the processors such as speculative execution of instructions, the complex effects of caches, and optimisations in the compilers. In this thesis we focus on the C11 memory model that is defined by the 2011 edition of the C standard. Our contributions are threefold. First, we focused on the theory surrounding the C11 model, formally studying which compiler optimisations it enables. We show that many common compiler optimisations are allowed, but, surprisingly, some important ones are forbidden. Secondly, building on our results, we developed a random testing methodology for detecting when mainstream compilers such as GCC or Clang perform an incorrect optimisation with respect to the memory model. We found several bugs in GCC, all promptly fixed. We also implemented a novel optimisation pass in LLVM, that looks for special instructions that restrict processor optimisations - called fence instructions - and eliminates the redundant ones. Finally, we developed a user-level scheduler for lightweight threads communicating through first-in first-out single-producer single-consumer queues. This programming model is known as Kahn process networks, and we show how to efficiently implement it, using C11 synchronisation primitives. This shows that despite its flaws, C11 can be usable in practice.