Travail de Bachelor

NEXT GENERATION DIGITAL ARITHMETIC

±∞

P 0 sit DANS Rapport final

Auteur: Baeriswyl Julien Superviseur: Dassati Alberto (ADI)

27 juillet 2018

Table des matières

1 Préface 9 1.1 Remerciements...... 9 1.2 Résumé...... 9

2 Introduction 11 2.1 Contexte...... 11 2.1.1 Cadre de déroulement...... 11 2.1.2 Contexte informatique...... 11 2.1.2.1 Types de représentation de nombres...... 11 2.1.2.2 Pourquoi a-t-on besoin d’une alternative ?...... 11 2.1.2.3 Alternatives à l’heure actuelle...... 11 2.1.2.3.1 Inconvénients des alternatives...... 12 2.1.2.3.2 Pourquoi les Posits ?...... 12 2.2 Objectif principal...... 12 2.3 Objectifs pratiques...... 12

3 Notions mathématiques 13 3.1 Ensemble de nombres...... 13 3.2 Représentations des nombres...... 13 3.3 Notation scientifique...... 14 3.4 Nombres dans l’informatique...... 14 3.4.0.1 Problèmes liés aux approximations...... 14 3.4.1 Nombres entiers...... 15 3.4.2 Nombres à virgule...... 15 3.4.3 Principe de clôture...... 15 3.4.4 Arithmétique d’intervalles...... 15 3.4.5 Real projective line ...... 15 3.4.6 Arithmétique multi-précision...... 16 3.4.7 Tapered floating point ...... 16

4 Nombres à virgule flottante ou floating-point 17 4.1 Représentations standards IEEE Std 754-1985/ IEEE Std 754-2008...... 17 4.1.1 Formats binaires...... 17 4.1.1.1 Exposant...... 17 4.1.1.2 Mantisse...... 17 4.1.1.3 Bit implicite...... 17 4.1.1.4 Signe...... 17 4.1.1.5 Représentations spéciales...... 18 4.1.1.6 Signification selon le champ exposant...... 18 4.1.1.7 Example...... 18 4.1.2 Intervalles dynamiques...... 19 4.1.2.1 Distribution des nombres sur l’intervalle...... 19 4.1.3 Particularités...... 19 4.1.4 Inconvénients...... 19 4.2 Représentations alternatives...... 19 4.3 Support dans les systèmes informatiques...... 20 4.3.1 Méthodes de support...... 20

3 Département TIC, 27 juillet 2018

4.3.2 Support logiciel...... 21 4.3.3 Support matériel...... 21 4.3.4 Support dans GNU/Linux ...... 21 4.3.4.1 GNU Toolchain (GCC,...) ou LLVM ?...... 21

5 À propos des Universal Numbers ou Unum 22 5.1 Historique...... 22 5.2 Unum I...... 22 5.2.1 Buts...... 22 5.2.2 Format...... 22 5.2.2.1 Organisation des champs...... 22 5.2.2.2 Signification des champs...... 23 5.2.3 Application...... 23 5.3 Unum II...... 23 5.3.1 Buts...... 23 5.3.2 Principes...... 23 5.3.2.1 Encodage SORN...... 23 5.3.3 Format...... 24 5.4 Unum III...... 24 5.4.1 Buts...... 24 5.4.2 Première variante, le Posit ...... 24 5.4.2.1 Particularités...... 24 5.4.2.2 Format...... 24 5.4.2.2.1 Organisation des champs...... 24 5.4.2.2.2 Signification des champs...... 25 5.4.2.3 Le champ regime ...... 25 5.4.2.4 Équivalence avec le standard IEEE Std 754-2008 ...... 26 5.4.2.5 Exemple de format...... 26 5.4.2.6 Méthodes de calcul...... 27 5.4.2.7 Algorithmes...... 28 5.4.3 Seconde variante, le Valid ...... 30 5.4.3.1 Format...... 30 5.5 Implémentations des Posits ...... 30 5.5.1 Logicielles...... 30 5.5.2 Matérielles (soft-core)...... 30 5.5.3 Observations...... 31

6 Réalisation du projet 32 6.1 Structure du projet...... 32 6.2 Licence logicielle...... 32 6.3 Émulation logicielle floating-point dans GNU/Linux ...... 32 6.3.1 Du côté noyau...... 32 6.3.2 Architectures supportées par la GNU Toolchain ...... 32 6.4 Immersion dans la GNU Toolchain...... 33 6.4.1 Infrastructure...... 33 6.4.1.1 Pré-requis...... 33 6.4.1.2 Composants...... 33 6.4.1.3 Organisation des sources...... 33 6.4.1.4 Types de fichiers...... 34 6.4.2 Fonctionnement de GCC ...... 34 6.4.2.1 Front-end...... 34

4 Département TIC, 27 juillet 2018

6.4.2.2 Back-end...... 34 6.4.3 Options floating-point à la compilation d’une application...... 34 6.4.3.1 ARM ABI s : OABI vs EABI ...... 35 6.4.3.2 Usage des ressources matérielles...... 35 6.4.3.3 Lien dans les applications...... 35 6.4.3.4 Implémentations des routines...... 35 6.5 Mécanismes à gérer...... 35 6.6 Considérations sur le développement...... 36 6.6.1 Interventions dans les sources...... 36 6.6.2 Version de GCC ...... 36 6.7 Méthodes d’intégration...... 36 6.7.1 Aspect fonctionnel...... 36 6.7.1.1 Bénéfice pour l’utilisateur...... 36 6.7.2 Portabilité...... 36 6.7.2.1 Types entiers natifs...... 37 6.7.2.2 Support de la cible...... 37 6.7.3 Remplacement...... 37 6.7.3.1 Approche générique...... 37 6.7.4 Ajout...... 37 6.7.5 Principes algorithmiques de l’implémentation générique...... 38 6.8 Mise en place des Posits dans la GNU Toolchain ...... 38 6.8.1 Méthode de mise en place...... 38 6.8.2 Modification de GCC ...... 38 6.8.3 Modification de Binutils ...... 39 6.9 Choix de la cible et de l’environnement hôte...... 39 6.9.1 Environnement cible...... 39 6.9.1.1 Plate-formes...... 39 6.9.1.2 Système d’exploitation...... 39 6.9.2 Outils de développement...... 39 6.9.2.1 Moteurs de production...... 39 6.9.2.2 Outils d’analyse...... 40

7 Tests 41 7.1 Méthodologie...... 41 7.1.1 Types de tests...... 41 7.1.2 Tailles de Posits ...... 41 7.1.3 Ressources de tests...... 41 7.1.4 Facteurs limitants...... 41 7.1.5 Choix de la batterie de tests...... 42 7.1.5.1 Tests unitaires...... 42 7.1.5.2 Tests fonctionnels...... 42 7.1.5.3 Tests de performance...... 42 7.1.6 Choix des plate-formes de test...... 42 7.2 Tests logiciels...... 42 7.2.1 Wrappers ...... 42 7.2.2 Bancs de test...... 42 7.2.3 Benchmarking ...... 43 7.3 Améliorations et tests manquants...... 43 7.4 Résultats des tests...... 43 7.5 Hardware de test...... 43 7.5.1 Machines hôtes...... 43

5 Département TIC, 27 juillet 2018

7.5.2 Plate-formes cibles (embarquées)...... 44

8 Conclusion 45 8.1 Résultats obtenus...... 45 8.2 Gestion du temps...... 45 8.2.1 Quelles auraient été les mesures à prendre ?...... 45 8.3 Difficultés rencontrées...... 45 8.4 À poursuivre dans le futur...... 46

Glossaire 47

Bibliographie 48

9 Authentification 52

Annexes 53

A Journal de travail 54 9.1 Révisions du document...... 54 9.2 Planification initiale...... 54 9.2.1 Suivi du planning...... 54 9.3 État actuel d’avancement...... 55 9.3.1 Processus d’intégration à GCC 6.4.0...... 55 9.4 Planification à mi-travail...... 56

6 Table des figures

3.1 Diagramme de la real projective line[9]...... 15 4.1 Diagramme de précision selon l’ordre de grandeur [24]...... 20 5.1 Exemple de représentations SORN[2] sur 3 bits...... 24 5.2 Organisation bit à bit d’un Posit[3]...... 24 5.3 Régime des réels positifs pour des Posit[3]...... 25 5.4 Table d’équivalence entre IEEE Std 754-2008 et Posits[3]...... 26 5.5 Real Projective Line pour des Posit<6,1>[3]...... 26 5.6 Format des Valids[3]...... 30

7 Liste des tableaux

4.1 Intervalles dynamiques [3] approximatifs pour le standard IEEE Std 754-2008...... 19 5.1 Organisation bit à bit d’Unum I...... 22 5.2 Signification des champs d’Unum I...... 23 5.3 Signification des champs d’un Posit ...... 25 5.4 Liste non exhaustives d’implémentations logicielles...... 30 5.5 Liste non exhaustives d’implémentations matérielles...... 30 6.1 Arborescence grossière du projet...... 32 6.2 Liste des pré-requis principaux de la GNU Toolchain ...... 33 6.3 Liste des composants principaux de la GNU Toolchain ...... 33 6.4 Type de sources dans GCC ...... 34 6.5 Liste des sources modifiées dans GCC ...... 38 6.6 Liste des sources modifiées dans Binutils ...... 39

8 Chapitre 1 Préface

1.1 Remerciements

Je tiens à remercier mon superviseur, Alberto Dassati, pour ses suggestions et indications, qui m’ont été d’un grande aide et également source d’inspiration.

Je tiens également à remercier le Dr. Artur Podobas, un chercheur de l’Institut de Technologie de Tokyo, qui est intervenu durant la Conference for Next Generation Arithmetic. Ses éclairages concernant l’avenir de ses recherche et l’avenir du format Posit m’ont aidé à décider plus précisément la direction que devait prendre mon travail.

1.2 Résumé

L’informatique, bien qu’elle soit une science, est avant tout un outil. Un outil est appréciable lorsqu’il est efficace, rapide, précis et mais surtout lorsqu’il est adapté aux besoins des êtres humains.

Dans l’informatique numérique, différentes représentations de nombres existent, afin de pouvoir utiliser la représentation qui convient le mieux aux besoins du moment. L’une de ces représentations est la virgule flottante, inspirée de la notation scientifique. Les formats couramment utilisés de cette représentation proviennent du IEEE Std 754-1985 et de sa révision IEEE Std 754-2008.

Bien que ces formats peuvent sembler avantageux, ceux-ci possèdent de nombreux défauts, dont une représentation de taille fixe qui ne s’adapte pas aux nombres représentés et qui comporte de la redondance d’information. De plus, leur mise en oeuvre est loin d’être anodine, autant en logiciel qu’en matériel, même pour des constructeurs chevronnés de puces électroniques. Cependant, ces formats sont les seuls officiellement supportés dans la programmation conventionnelle. Autrement dit, un développeur voulant utiliser une alternative doit développer son logiciel spécifiquement pour cette alternative.

Alors pourquoi ne pas développer une alternative destinée à remplacer le standard actuel et la mettre en place dans les outils de développement ?

Répondre à cette question est l’un des buts finaux de ce projet. Au fil du temps, de nombreuses alternatives ont vu le jour, généralement pour des usages particuliers, comme la compression de données, le traitement du signal ou encore le calcul vectoriel et matriciel.

Une alternative se distingue du lot par son jeune âge et ses ambitions : Unum ou Universal Numbers, élaboré par le Dr. John Leroy Gustafson. Les objectifs principaux à l’élaboration du format sont l’économie d’énergie (notamment par l’économie de bande passante), la simplification des circuits, une précision optimisée lors des calculs, ainsi qu’une meilleure gestion d’erreur. Encore en cours d’évolution, cette alternative se décline actuellement en 3 versions avec la dernière, comportant les variantes Posit et les Valid, sortie en février 2017. De plus, suite à la Conference for Next Generation Arithmetic du 28 mars 2018, les Posits sont destinés à être standardisés.

Ce projet vise alors l’intégration des Posits aux outils de développement courants, tels que GCC, pour finalement s’utiliser de manière transparente dans GNU/Linux. Dans une première phase, l’intégration est logicielle, tout d’abord sous la forme d’émulation, puis dans une phase ultérieure, une accélération sera faite matériellement, potentiellement sur FPGA comme point de départ.

9 Département TIC, 27 juillet 2018

Le challenge principal réside dans l’intégration logicielle, car les outils de développement sont complexes, parfois anciens et ne sont pas nécessairement conçus de manière intuitive. À l’heure actuelle, l’intégration est encore loin d’être complète, mais dans un avenir proche, celle-ci sera corrigée et complétée.

Lorsque ce projet sera finalisé, les développeurs seront en possession d’une solution proposant nativement une représentation alternative efficace pour la virgule flottante, sans effort de développement particulier pour leurs logiciels.

10 Chapitre 2 Introduction

Ce chapitre fournit seulement les grandes lignes du projet sans les détails techniques, qui seront présentés dans les chapitres suivants.

2.1 Contexte

Ce travail de bachelor se concentre sur l’exploitation d’alternatives au standard IEEE Std 754-2008 dans des projets libres existants. Est abordé ici l’usage des Posits, une variante de la 3e version d’une alternative nommée Unum pour Universal Numbers.

2.1.1 Cadre de déroulement Ce projet se déroule dans le cadre d’un travail de bachelor en Informatique Embarquée, à la Haute École d’Ingénierie et de Gestion du canton de Vaud (HEIG-VD), en Suisse.

2.1.2 Contexte informatique 2.1.2.1 Types de représentation de nombres En informatique, les 3 principaux types de représentation de nombres utilisés au besoin sont : — Les nombres naturels (non signés) et entiers (signés) — Les nombres rationnels, en virgule fixe — Les nombres rationnels, en virgule flottante Les processeurs à usage général gèrent au moins les nombres entiers. Les nombres rationnels à virgule fixe peuvent être émulés facilement de manière logicielle, mais des accélérateurs existe comme les processeurs de signal numérique ou Digital Signal Processors (DSP). Ces 2 types de nombres ne possèdent pas de formats standardisés et les représentations sont alors totalement au bon vouloir des concepteurs de puces électroniques.

En revanche, il existe un standard pour les nombres rationnels à virgule flottante. Ce standard, établi par l’Institute of Electrical and Electronics Engineers (IEEE), est largement supporté nativement au sein plate-formes matérielles et/ou logicielles.

2.1.2.2 Pourquoi a-t-on besoin d’une alternative ? Le standard IEEE Std 754-2008, bien que révisé en 2008, possèdent de nombreux inconvénients aussi bien matériels que logiciels. En outre, la représentation n’est pas conçue selon les besoins d’aujourd’hui.

Une meilleure clôture sur les opérations arithmétiques et une perte minimale d’information est un avantage pour tout logiciel nécessitant la précision des résultats.

Ces caractéristiques serait utile pour n’importe quel logiciel ayant la nécessité d’utiliser le floating-point. Toutefois, comme la compatibilité binaire n’est pas garantie, ceci est potentiellement inexploitable pour d’anciens logiciels non maintenus.

2.1.2.3 Alternatives à l’heure actuelle De nombreuses alternatives, qui seront introduites dans le chapitre suivant, ont été développées depuis 1960, sans pour autant aboutir à un nouveau standard. Le Posit est la future exception, car un brouillon de standard est en cours de rédaction, suite à la Conference for Next Generation Arithmetic du 28 mars 2018.

11 Département TIC, 27 juillet 2018

2.1.2.3.1 Inconvénients des alternatives Les alternatives sont utilisables par le biais de ressources logicielles externes aux bibliothèques logicielles standards et au système d’exploitation. En d’autres termes, le support des alternatives n’est pas natif au système utilisé. Par conséquent, l’usage d’une alternative nécessite que le logiciel qui l’utilise soit modifié en conséquence par le développeur, potentiellement de manière profonde.

2.1.2.3.2 Pourquoi les Posits ? Quelque soit la version d’Unum, celle-ci offre une meilleure gestion des erreurs et contrôle des valeurs.[1][2][3] Le Posit est une variante moderne et relativement simple tout en étant facilement adaptable au besoin. De plus, un standard est en cours d’établissement.

2.2 Objectif principal

Le but de ce projet est d’offrir un support natif à GNU/Linux d’une alternative au standard IEEE Std 754-2008, pour au moins une architecture matérielle.

Dans un premier temps, un support logiciel avec émulation sera mis en place. Puis dans un second temps, si possible dans le temps imparti au travail de bachelor, une accélération matérielle sera mise en place sur Field Programmable Gate Array (FPGA).

2.3 Objectifs pratiques

Deux cas d’applications seront traités ici : — Le remplacement d’émulation logicielle des nombres à virgule flottante (floating-point) dans GNU/Linux par un équivalent Unum. — L’accélération par la déportation d’une partie ou totalité des calculs sur la FPGA d’un System-on-Chip avec FPGA, tel que le Cyclone-V SoC d’Altera. Les cas d’applications sont utilisés à des fins expérimentales, afin de montrer ou confirmer que : — L’alternative est plus efficace que le standard IEEE Std 754-2008 sur le plan algorithmique. — L’alternative est plus fiable sur le plan numérique. — L’accélération matérielle pour l’alternative est plus abordable que le standard IEEE Std 754-2008.

12 Chapitre 3 Notions mathématiques

3.1 Ensemble de nombres

On a N ⊂ Z ⊂ Q ⊂ R ⊂ C, où :

Ensemble Description N naturels 0, 1, 2, ... Z entiers ..., -2, -1, 0, 1, 2, ... Q rationnels p ÷ q, p, q ∈ Z R réels contenant les irrationnels tels que π C nombres complexes Z = a + bi, a, b ∈ R

3.2 Représentations des nombres

Pour représenter les nombres de manière universelle, l’humanité utilise certaines conventions similaires à celle utilisées dans l’écriture d’une langue. En effet, certains nombres particuliers possèdent leur propre symbole, alors que les autres sont représentés grâce à une base numérique.

Une base numérique est méthode de représentation par des séquences d’un ensemble de N symboles distincts ou chiffres, qui représentent chacun une valeur invariante précise. La position des symboles dans la séquence est significative. La position de chaque symbole réfère implicitement à une puissance de la base, la position la plus à gauche étant la plus significative. Par exemple, la base 10 utilise 10 symboles : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 .

Par décomposition en base 10, on obtient par exemple :

1043 = 1 · 1000 + 0 · 100 + 4 · 10 + 3 · 1 = 1 · 103 + 0 · 102 + 4 · 101 + 3 · 100 Le principe fonctionne toujours, même pour les nombres à virgule :

3.14 = 3 · 1 + 1 · 0.1 + 4 · 0.01 = 3 · 100 + 0 · 10−1 + 4 · 10−2 Les nombres en base 10 sont alors des sommes de puissance de 10 :

X i x = 10 ci, x ∈ R, ci ∈ {0, ..., 9} i∈Z Par généralisation dans une base quelconque :

X i x = b ci, x ∈ R, ci ∈ {0, ..., b − 1} i∈Z Ce type de système possède certains inconvénients, car il existe des nombres qui ne sont pas représentables de manière finie. En effet, les nombres irrationnels nécessitent une infinité de chiffres après la virgule. De 1 même que certains nombres rationnels ne sont pas représentables dans toutes les bases, tels que 3 en base 10.

À noter qu’il est impossible de stocker totalement un nombre dont la représentation n’est pas finie, car la matière nécessaire est limitée dans l’univers. Il est alors essentiel de faire des compromis et d’utiliser des approximations lors de calculs numériques.

13 Département TIC, 27 juillet 2018

3.3 Notation scientifique

Pour pallier au problème de représentation trop grande à écrire, autant pour l’humain que pour les machines, la notation scientifique est utilisée. Le principe consiste à mémoriser les chiffres les plus significatifs en mentionnant l’ordre de grandeur sous forme exponentielle. Par exemple :

π ' 3.14159265359 = 3.14159265359 · 100 Ou pour le nombre d’Avogadro, en base 10 :

23 NA ' 6.02214075862 · 10

3.4 Nombres dans l’informatique

La base numérique de référence en informatique est la base 2 ou binaire, car créer 2 états stables au niveau physique est plus facile et fiable qu’en créer plus. Le risque d’erreur est minimisé et la détection et correction plus simple. Les représentations couramment utilisées ne correspondent pas exactement aux notations mathématiques, car : — il n’existe pas de symboles spéciaux pour le signe des nombres, qui est alors représenté de manière binaire. — des compromis sont fait afin de minimiser la complexité du matériel. Il existe une distinction entre les représentations numériques des entiers et des nombres à virgule. En effet, le comportement des nombres à virgule présente une particularité supplémentaire, car les multiplications et divisions peuvent modifier la précision nécessaire au stockage du résultat exact :

x, y > 1 =⇒ xy > x ∧ xy > y x, y < 1 =⇒ xy < x ∧ xy < y Par exemple, pour une puissance d’un nombre à virgule :

(0.1)8 = (0.01)4 = (0.0001)2 = 0.00000001 (2.5)8 = (6.25)4 = (39.0625)2 = 1525.87890625 La taille de représentation croit alors environ 2 fois plus vite que pour un entier.

À noter que les représentations sont de taille finie, au même titre que la mémoire. Ceci implique que ces représentations ne couvre que des sous-ensembles des entiers et rationnels. Les autres nombres ne peuvent pas être représentés, mais certains peuvent être remplacés par des approximations. Autrement dit, la représentation informatique des nombres réels est une discrétisation d’un intervalle connu.

3.4.0.1 Problèmes liés aux approximations Les représentations informatiques des réels ne sont pas systématiquement exactes, ne serait-ce qu’à cause des nombres irrationnels. Les approximations engendrent des erreurs qui se cumulent et se reportent dans les calculs successifs. Le premier problème apparaît dans la réciprocité des opérations et des fonctions. Par exemple :

3 · 0.3333333333 6= 3 · 0.3 = 3 · 1 3 (3.1) ⇐⇒ 0.9999999999 6= 1 Autrement dit, la multiplication n’est plus systématiquement l’opération réciproque de la division. Il en va de même pour les fonctions exponentielles et logarithmes.

14 Département TIC, 27 juillet 2018

3.4.1 Nombres entiers La difficulté principale de représentation des entiers est la gestion du signe. Les quelques représentations les plus utilisées sont [4]: — Le complément à 2, asymétrique par rapport à 0, avec un nombre de plus dans l’intervalle discret négatif. — Le complément à 1, symétrique, mais possédant 0 et -0, le second n’ayant pas de sens mathématique. — La magnitude de signe, ou 1 bit de signe en poids fort indique si le nombre est positif ou négatif. Possède également -0 comme valeur de 0. — Entier biaisé ou (excess-K), où l’intervalle discret est mappé sur un intervalle équivalent non-négatif. — Usage de la base négative -2. Le complément à 2 est majoritairement utilisé au niveau matériel[4][5], comme par les processeurs d’Intel et d’ARM, par contre les machines UNISYS utilisent le complément à 1[5].

3.4.2 Nombres à virgule Les représentations de nombres à virgule sont généralement représentés de 2 manières différentes : — La virgule fixe, utilisée notamment par les Digital Signal Processor (DSP). — La virgule flottante, utilisée notamment dans les Graphics Processing Unit (GPU). La spécification de la virgule flottante la plus couramment utilisée est le standard IEEE Std 754-2008.

3.4.3 Principe de clôture Une opération binaire # est close ou stable sur un ensemble E si et seulement si :

x#y ∈ E, ∀x, y ∈ E (3.2)

3.4.4 Arithmétique d’intervalles L’objectif est le rigorisme des résultats en palliant aux problèmes résultant des approximations dans les représentations informatiques des réels. L’arithmétique d’intervalle[6][7] utilise les intervalles plutôt que directement des nombres pour effectuer des calculs. Un intervalle est représenté par une paire de nombres. Ceci permet d’exprimer les résultats comme des intervalles bornés. Si l’intervalle possède un seul élément (sauf infinis et autres exceptions), alors le résultat est exact. De plus, cette méthode permet de définir une résolution des opérations sur tous les cas d’exceptions (infinis, ...).

3.4.5 Real projective line Le principe de real projective line[8] est une déformation conceptuelle de la droite des réels, qui possède 2 extrémités irrationnelles distinctes que sont les infinis négatif et positif. Dans la real projective line, il n’existe qu’un seul infini représenté par un point, auquel sont associés les extrémités de la ligne de réels. ∞

0

Figure 3.1 – Diagramme de la real projective line[9]

15 Département TIC, 27 juillet 2018

Les extrémités infinies se rejoignent pour former un cercle, dont la symétrie met face à face : — 0 et ±∞ en vertical — 1 et -1 en horizontal

3.4.6 Arithmétique multi-précision L’arithmétique multi-précision[10] est un principe visant à utiliser des représentations de tailles arbitraires, dont les limites ne résident pas dans les capacités des unités matérielles de calculs, mais dans la taille de la mémoire du système. Par exemple : — Le langage Python maîtrise de manière transparente ce mécanisme pour les entiers signés. — Le langage Java possède la classe BigInteger qui implémente cette fonctionnalité. — Le langage C ne possède pas directement de mécanisme, mais la bibliothèque GNU Multiple Precision Arithmetic Library (GMP) implémente cette fonctionnalité.

3.4.7 Tapered floating point Dans les représentations standardisées du floating-point, les tailles de champs sont fixes, ce qui implique que ces représentations peuvent manquer de précision ou en gaspiller. Le principe de tapered floating point[11][12] permet des champs de tailles variable, permettant ainsi d’adapter dynamiquement la représentation selon les besoins du moment. Ce compromis peut engendrer un surcroît de complexité de décodage des données. Les Unums utilisent ce principe.

16 Chapitre 4 Nombres à virgule flottante ou floating-point

4.1 Représentations standards IEEE Std 754-1985/ IEEE Std 754-2008

Ce standard, émis par l’Institute of Electrical and Electronics Engineers, utilise une représentation basée sur la notation scientifique. Chaque représentations comporte 3 champs, de taille spécifiquement choisie afin d’avoir un compromis entre précision et intervalle dynamique couvert. La révision de 2008 concerne notamment : — Les formats binaires demi, quadruple et octuple précisions. — Les formats décimaux double et quadruple précisions. — L’opérateur fusionné multiplication-addition. Dans cette section, toutes les tailles mentionnées ici sont en bits, avec es étant la taille d’exposant et ms la taille de mantisse.

4.1.1 Formats binaires

Format Taille Signe Exposant Bit implicite Mantisse Mantisse/Exposant binary16 16 1 5 1 10 2.000 binary32 32 1 8 1 23 2.875 binary64 64 1 11 1 52 4.727 binary128 128 1 15 1 112 7.467 binary256 256 1 19 1 236 12.421

Le bit implicite, qui est le bit le bit le plus significatif de la mantisse, n’est pas stocké. La taille de mantisse grandit presque exponentiellement en comparaison la taille d’exposant.

4.1.1.1 Exposant L’exposant est ici un entier signé avec l’encodage excess-K.

champexposant = exposant − biais = exposant − (2es−1 − 1)

4.1.1.2 Mantisse La mantisse contient la partie fractionnelle de la notation scientifique. Le bit de poids fort est rendu implicite avec l’encodage et n’est alors pas mémorisé dans le format.

4.1.1.3 Bit implicite Selon la valeur de l’exposant, le bit implicite est interprété ou non.

Exposant Bit implicite 0 0 1..1 don’t care ]0, 1..1[ 1

4.1.1.4 Signe

Valeur Signe correspondant 0 Positif 1 Négatif

17 Département TIC, 27 juillet 2018

4.1.1.5 Représentations spéciales Certains calculs peuvent aboutir à des résultats non-numériques ou sans signification mathématique : — Infinis positif ou négatif pour lesquels il n’existe pas d’approximations. Par exemple, 1.0/0.0 ou -1.0/0.0 aboutissement à ces résultats. — Not a Number, qui indique un résultat mathématiquement invalide. Par exemple, 0.0/0.0 aboutit à ce résultat.

4.1.1.6 Signification selon le champ exposant Ici, k, M, G, P sont les préfixes du Système International d’Unités (SI) pour les puissances de 2. Le symbole ϕ signifie don’t care.

Signe Exposant Mantisse Sens Quantité binary16 binary32 binary64 binary128 0 1..1 = 0 +∞ 1 1 1 1 1 1 1..1 = 0 −∞ 1 1 1 1 1 ϕ 1..1 6= 0 Not a Number 21+ms 2k 16M 8P 2113 0 0 ϕ x ∈ [0, 1[ 2ms 1k 8M 4P 2112 1 0 ϕ x ∈] − 1, −0] 2ms 1k 8M 4P 2112 0 ]0, 1..1[ ϕ x ∈ [1, +∞[ 2ms(2es − 2) 30k 2032M 8176P 2112(215 − 2) 1 ]0, 1..1[ ϕ x ∈] − ∞, −1] 2ms(2es − 2) 30k 2032M 8176P 2112(215 − 2)

4.1.1.7 Example

3.75 = 0b11.11 = 0b1.111 ∗ 21 Converti en IEEE-754 binary16, on a :

signe = 0 exposant = 1 (4.1) bitimplicite = 1 mantisse = 0b111 Le champ exposant est :

efield = exposant − biais = 1 − (2es−1 − 1) = 1 − (25−1 − 1) = 1 − (24 − 1) (4.2) = 1 − (16 − 1) = 1 − 15 = −14 = 0b10010

3.75 = 0100101110000000 , avec le bit implicite à 1

18 Département TIC, 27 juillet 2018

4.1.2 Intervalles dynamiques

Format Minimum en valeur absolue Maximum en valeur absolue binary16 3. × 10−8 7. × 104 binary32 7. × 10−46 3. × 1038 binary64 2. × 10−324 2. × 10308 binary128 3. × 10−4966 1. × 104932 binary256 1. × 10−78984 2. × 1078913

Table 4.1 – Intervalles dynamiques [3] approximatifs pour le standard IEEE Std 754-2008

4.1.2.1 Distribution des nombres sur l’intervalle Pour chaque valeur d’exposant, on a 2ms nombres possibles, au signe près. Par conséquent, la distribution des nombres n’est pas uniforme sur l’intervalle dynamique, mais logarithmique.

4.1.3 Particularités — Deux représentations du zéro : 0.0 et -0.0. — Beaucoup de représentations du NaN, alors qu’un seul suffirait. — Représentation signée de l’infini, 2 symboles en tout. — Nombres normalisés dans l’ensemble ] − ∞, −1][1, +∞]. — Nombres dé-normalisés dans l’ensemble ] − 1, 1[.

4.1.4 Inconvénients — Les calculs peuvent amener à des résultats inexacts qui sont tronqués ou arrondis. Ces inexactitudes ne sont pas signalées dans le format. — Gaspillage de séquences binaire, comme pour les NaN. — Bande-passante conséquente. — Circuits compliqués pour le traitement des opérations. — Consommation énergétique élevée, autant pour les circuits dédiés que pour les transferts de données jusqu’à la mémoire principale.[1]. — Pas toujours évident de garantir la conformité avec le standard, même pour des spécialistes comme Nvidia[13].

4.2 Représentations alternatives

À cause des nombreux inconvénients, cas limites et problèmes liés aux formats standards, y compris IEEE Std 754-2008, d’autres méthodes de représentations et calculs ont été explorées. De plus, suite à la Conference for Next Generation Arithmetic du 28 mars 2018, de nouvelles alternatives ont été proposées.

Voici quelques exemples :

19 Département TIC, 27 juillet 2018

Nom Concepteur Année Objectifs KAA[14] Université de Karlsruhe 196x Réduction d’erreurs et arrondis pour le produit scalaire LNS[15][16] N. Kingsbury, P. Rayner 1971 Simplifier le traitement matériel de signal grâce aux logarithmes Elias γ[17] Peter Elias 1975 Représenter des entiers positifs Elias δ[18] Peter Elias 1975 Représenter des entiers positifs à borne supérieure inconnue Elias ω[19] Peter Elias 1975 Compression des entiers positifs par probabilité d’occurence URR[20][21] HAMADA, Hozumi 1987 Indépendance de la taille, supprimer les overflow et underflow Unum I[1] Dr. J. L. Gustafson 2015 Économie d’énergie et de stockage, calculs simples, moins d’erreurs Unum II[2] Dr. J. L. Gustafson 2016 Matériel peu coûteux et rapide, résolution des cas limites Unum III[22] Dr. J. L. Gustafson 2016 Tapered precision, calculs simplifiés, meilleure clôture des opérations Slide[23] Ignaz Kohlbecker 2018 Meilleure couverture des nombres en sciences expérimentales

La figure ci-dessous illustre le nombre de bits de précision disponibles de certaines de ces représentations, selon la valeur de l’exposant.

float binary(8) gamma posit(1) posit(2) delta omega 30 29 28 27 26 25 24 23 22 precision 21 20

19 18 17 16 -48 -44 -40 -36 -32 -28 -24 -20 -16 -12 -8 -4 0 4 8 12 16 20 24 28 32 36 40 44 48 exponent

Figure 4.1 – Diagramme de précision selon l’ordre de grandeur [24]

Certaines de ces représentations, dont les Posits, utilise la notion de projective reals.

4.3 Support dans les systèmes informatiques

Le standard spécifie le format ainsi que le comportement des résultats lors des calculs, mais n’indique pas comment l’implémentation doit être faite. Celle-ci est alors à la discrétion des constructeurs de processeurs et d’accélérateurs spécialisés et des développeurs de logiciels.

4.3.1 Méthodes de support Le support de la virgule flottante dépend directement de l’architecture matérielle et logicielle du système utilisé. Il existe 4 grandes méthodes de support (du plus rapide au plus lent pour une donnée isolée) : — Directement dans le CPU, avec des instructions dédiées — Coprocesseur intégré au CPU, avec des instructions dédiées — Par l’intermédiaire d’un coprocesseur externe au CPU

20 Département TIC, 27 juillet 2018

— Par émulation entièrement logicielle, qu’elle soit native ou non au système d’exploitation. L’émulation logicielle est de loin la solution la plus lente pour une donnée isolée, dans la mesure où les opérations sont faites par des algorithmes utilisant les entiers et pouvant durer plusieurs centaines d’instructions. La préférence va alors aux accélérations matérielles lorsqu’elles sont disponibles.

4.3.2 Support logiciel Le support logiciel possède la responsabilité de permettre au programmeur de recourir à la virgule flottante selon ses besoins et la cible du programme. Dans tous les cas, les instructions générées vont dépendre du type de support présent sur la cible. Le support logiciel concerne : — La cible matérielle. — Les instructions machine. — Le noyau du système. Dans le cas d’une émulation logicielle, le support peut se faire par : — Une bibliothèque logicielle tierce tels que Berkeley SoftFloat, ce qui nécessite alors une implémentation en conséquence de l’application. — Des routines user-space internes à l’application compilée, liées statiquement. — Des routines user-space externes à l’application compilée, liées dynamiquement. — Des instructions levant une exception traitée par le noyau du système d’exploitation, qui va appelé les routines kernel-space correspondantes. La dernière méthode est peu recommandée, car elle nécessite un changement de contexte de l’application vers le noyau, ce qui coûteux en temps.

Le support natif logiciel dans un système passe alors par : — La toolchain, qui génère les instructions ou les routines nécessaires. — Le noyau du système d’exploitation, lorsque nécessaire.

4.3.3 Support matériel — CPU d’Intel et d’ARM (pas tous) — Extensions SIMD (SSE2, ...) — Accélérateurs dédiés, comme : — Graphics Processing Units (GPU) de Nvidia[13] et AMD — Tensor Processing Units (TPU) de Google

4.3.4 Support dans GNU/Linux Le support dans les environnements GNU/Linux concerne toutes les méthodes mentionnées précédemment. L’émulation logicielle implique le noyau et la toolchain. À noter que la méthode utilisant les exceptions existe, mais celle-ci a été abandonnée au profit des appels de routines user-space.

4.3.4.1 GNU Toolchain (GCC,...) ou LLVM ? Bien que LLVM soit supporté dans GNU/Linux, GCC pré-domine à l’usage, d’où le choix de celui-ci dans ce projet. De plus, les sources de GNU/Linux utilisent certaines extensions propres à GCC, ce qui le rend dépendant de celui-ci, bien que des recherches aient eu lieu pour pouvoir compiler un GNU/Linux fonctionnel avec LLVM.

21 Chapitre 5 À propos des Universal Numbers ou Unum

Unum est un ensemble de formats alternatifs au standard IEEE Std 754-2008 pour les nombres à virgule flottante. Ces formats ont été proposé par Dr. J. L. Gustafson, un informaticien américain afin de remplacer le standard IEEE Std 754-2008, qu’il juge inadapté aux besoins actuels.

Unum est encore en cours d’évolution, suite aux critiques [25][26] des premières versions par d’autres chercheurs, tels que le Prof. William Kahan, un des cofondateur du standard IEEE Std 754-1985.

5.1 Historique

Depuis l’apparition d’Unum, 3 versions ont été publiées. Les nouvelles versions sont apparues après des critiques des précédentes, afin de converger vers le meilleur compromis entre précision, performance et stockage.

Version Année Description 1 2015 Sur-ensemble de IEEE Std 754-2008, rétro-compatible Méthode différente, utilise la résolution des nombres SORN grâce à des look-up tables, pas 2 2016 rétro-compatible 3-Posit 2017 Conversion possible vers le standard, non-rigoureux, plus proche des entiers en complément à 2 3-Valid 2017 Utilise une paire de Posit avec le bit d’incertitude

5.2 Unum I

5.2.1 Buts Les buts principaux sont : — L’économie de la bande passante, en ne stockant que l’information utile. — Une meilleure gestion d’erreur, en indiquant l’incertitude des résultats lors des calculs.

5.2.2 Format Ce format conserve le même principe de format que le standard IEEE Std 754-2008, mais avec les modification suivantes : — Un bit d’incertitude ajouté en poids faible permet d’indiquer si la valeur stockée est exacte ou arrondie. — L’exposant peut être de taille variable. — La mantisse peut être de taille variable. — 2 champs supplémentaires permettent d’indiquer la taille d’exposant et la taille de mantisse. Les champs esize et fsize sont optionnels lorsque les champs exposant et mantisse sont de tailles fixes. Les champs ubit, esize et fsize forment le utag.

5.2.2.1 Organisation des champs

Champ sign exponent fraction ubit esize fsize Bits N − 1 N-2 :N-(1+esize) N-(2+esize) :N-(1+esize+fsize) N-(2+esize+fsize) 6 :4 3 :0

Table 5.1 – Organisation bit à bit d’Unum I

La taille minimale est de 4 bits en absence de tailles variables, 5 ou 6 bits sinon.

22 Département TIC, 27 juillet 2018

5.2.2.2 Signification des champs

Nom Description sign LSB qui indique si le nombre est négatif exponent Exposant (2exponent) encodé en offset binary fraction Mantisse ubit Bit d’incertitude, 0 = exact, 1 = dans un intervalle esize Taille d’exposant en bits fsize Taille de fraction en bits

Table 5.2 – Signification des champs d’Unum I

5.2.3 Application L’inconvénient principal est le décodage des données puisque la taille est variable. Cela induit également une complexification du matériel nécessaire au traitement des données.

Il existe principalement des implémentations logicielles de ce format. Il existe au moins une implémentation pseudo-matérielle en VHDL [27], malheureusement non-synthétisable, créée par les instituts CEA-LETI et INSA-Lyon.

5.3 Unum II

5.3.1 Buts L’objectif de cette version est la rigueur de calcul. Toutefois, la méthode est limitée à des tailles inférieures ou égale à 20 bits, car la résolution s’effectue à l’aide de tables de correspondance (look-up tables). La méthode est peu coûteuse, car la logique est pratiquement absente, le décodage pouvant être stocké dans de simples mémoires.

5.3.2 Principes L’arithmétique d’intervalle est utilisée.

5.3.2.1 Encodage SORN Un SORN ou Set of Real Numbers est une représentation indiquant l’absence ou la présence d’un des 4 éléments, dans l’ordre d’encodage du bit de poids fort au bit de poids faible : — ±∞ — (−∞, 0) — {0} — (0, +∞) Cet encodage permet de résoudre tous les cas de formes indéterminées[2] lors de calculs.

23 Département TIC, 27 juillet 2018

100 ±∞ 101 011 Example SORN representations: (–∞, –1) (1, ∞) ▯○▯○ ▯○▯○ Empty set, ∅ 110 –1 1 010 ▯○▮○ ▯○▮○ Values satisfying x2 = 1, the set {–1, 1} (–1, 0) (0, 1) 111 001 ▮●▮● ▮●▮● Everything, [–∞, ∞] 0 000 Figure 5.1 – Exemple de représentations SORN[2] sur 3 bits

5.3.3 Format Ce format est incompatible avec le standard IEEE Std 754-2008, sans conversion possible.

5.4 Unum III

5.4.1 Buts La version 3 est un compromis entre performance, scalabilité et fiabilité. Celle-ci se décline en 2 variantes, dont le 2e est une extensions du 1er. L’un des principes utilisé dans ce format est l’encodage Golomb-Rice, une méthode compression sans perte.

5.4.2 Première variante, le Posit 5.4.2.1 Particularités Le Posit est un format non rigoureux des nombres à virgule flottante. Ce format utilise un système proche des entiers : — Les nombres négatifs sont en complément à 2. — Une unique représentation du 0.0. — Une unique représentation partagée entre les 2 infinis et NaN. Sa valeur est le complément à 2 de 0. — L’intervalle discret couvert est alors symétrique. — La mantisse comporte un bit implicite, toujours à 1.

5.4.2.2 Format 5.4.2.2.1 Organisation des champs

sign regime exponent fraction bit bits bits, if any bits, if any

s r r r r ⋯ r e1 e2 e3 ⋯ ees f1 f2 f3 f4 f5 f6 ⋯

nbits Figure 5.2 – Organisation bit à bit d’un Posit[3]

24 Département TIC, 27 juillet 2018

5.4.2.2.2 Signification des champs

Nom Description sign MSB qui indique si le nombre est négatif regime Exposant linéaire en complément à 1 ((22es)regime) exponent Exposant binaire en complément à 2 (2exponent) 1 fraction Mantisse ( fraction ) ubit (Valids uniquement) Bit d’incertitude

Table 5.3 – Signification des champs d’un Posit

4

3 0

5.4.2.3 Le champ regime ⋯ 2 0

1111 ±∞ useed useed Le régime est un exposant particulier, 111 useed ⋯ 0 ou celui est encodé comme une valeur 11 linéaire, par des leading one-bits en useed Regime 3 partant du bit de poids fort qui suit le Regime 2 signe. Regime 1

⋯ Il y a 2 cas de figure : 10 — La séquence commence par un 1 et Regime 0 se termine soit par un 0 ou part l’atteinte du bit de poids faible. Le 1 régime est alors positif (selon signe). — La séquence commence par un 0 et Regime- 1 se termine soit par un 1 ou part l’atteinte du du bit de poids faible. 01⋯

Le régime est alors négatif (selon Regime2-

signe). Regime3- 4Regime-

useed

- 1 00 1 ⋯ useed

000 useed 0 useed 0000 1 - 2 ⋯

1 -

- 3 ⋯ 4

Figure 5.3 – Régime des réels positifs pour des Posit[3] La valeur du régime se calcule comme suit (numérotation des bits de n − 1 à 0):

−CLZ(p[n − 2 : 0]), p[n − 1] = 0 ∧ p[n − 2] = 0  CLO(p[n − 2 : 0]) − 1, p[n − 1] = 0 ∧ p[n − 2] = 1 REGIME(p) = (5.1) −CLZ((−p)[n − 2 : 0]), p[n − 1] = 1 ∧ (−p)[n − 2] = 0  CLO((−p)[n − 2 : 0]) − 1, p[n − 1] = 1 ∧ (−p)[n − 2] = 1

, avec CLZ = count leading zeros et CLO = count leading ones.

25 Département TIC, 27 juillet 2018

5.4.2.4 Équivalence avec le standard IEEE Std 754-2008

Size, Float Float Posit Posit bits exponent size dynamic range es value dynamic range

16 5 3.×10- 8 to 7.×104 1 9.×10- 10 to 1.×109

32 8 7.×10- 46 to 3.×1038 3 2.×10- 75 to 5.×1074

64 11 2.×10- 324 to 2.×10308 4 4.×10- 304 to 3.×10303

128 15 3.×10- 4966 to 1.×104932 7 3.×10- 4894 to 3.×104893

256 19 1.×10- 78 984 to 2.×1078 913 10 1.×10- 78 605 to 9.×1078 604

Figure 5.4 – Table d’équivalence entre IEEE Std 754-2008 et Posits[3]

5.4.2.5 Exemple de format Voici un exemple complet des valeurs représentées pour des Posits de taille 6 avec 1 bit d’exposant : 100000 → 100001→

100010→

100011→ 0 1 100100→ 0 0 11111 0 100101→ 1111 + 1 + 111 - - 1 + 100110→ - 00000 111 0 11111 0 - 1111 + 1 111 11 - 100111→ + 0 111 1 - 11 0 11 0 0 + 0 011111→ 101000→ 1 011110→ - 0 11 0 11 0 0 011101→ 1 + 0 011100→ 0 - 1 ± ∞ 0 - 101001→ 11 1 - 011011→ 11 - 256 + 0 0 64 11 - - 32 011010→ 1 11 0 64 256 0 1 - 16 32 1 101010→ 0 12 16 011001→ + - 0 - 1 0 12 110 0 8 8 011000→ 0 1 - +1 101011→ - 11 6 6 1 - 010111→ 0 4 4 101 110 10 - - 010110→ + 101100→ 1 7 /2 01 /2 7 00 01 - 3 3 101 - 010101→ + 101 - 101101→ 00 5 /2 11 /2 5 010100→ 100 - 1 - + 0011 2 2 101110→ 010011→ - 7 /4 +10010 - 10010 /4 7 - 010010→ 101111→ 3/2 3/2 - 100 +10001 01 - 5/4 5/4 010001→ 110000→- 10000 - 1 1 010000→+10000 - 7/8 7/8 001111→ - 01111 +011 110001→ 4 3 11 - 3/ /4 001110→ - 01110 5/8 5/8 +01110 110010→ - 001101→ 1101 /2 1 - 0 - 1 /2 + 7 001100→ 011 110011→ 00 /16 /16 01 011 - 7 - /8 3/ 001011→ + 11 3 5 8 011 10 - /16 / 00 110100→ 0 16 → - - 5 4 1 001010 + 10 / 3 / 0 10 1 16 4 10 0 - / /16 001001→ 11 110101→ - 01 3 8 1 0 / 3 +0 1 - 32 1 / / 001000→ 1 1 1 8 0 / 16 1 32 0 - 00 - 1 / 10 / / 0 3 32 / 16 000111→ 110110→ 64 + / 256 / 1 1 256 32 0 - 1 / 64 0 1 / 1 - - 1 000110→ 0 1 1 1 0 - 0 + 01 1 - 000101→ 0 110111→ 00 - - 1 1 1 0 000100→ 0 0 000011→ + 00 00 1 00 - 0 1 000010→ 000001→ 111000→ 000000 → 00 1 1 0 1 + 1 - 1 00 1 00 1 + 111001→ - 000 1 00 1 - 000 + 0000 0 - 00 1 111010→ - + 0 + 000

+ 1 1 + 111011→ 000 0000 0 00000 0 1 111100→ 1 1

111101→ 0

1 111110→

111111→

Figure 5.5 – Real Projective Line pour des Posit<6,1>[3]

On constate que : — L’opposé est fait grâce au complément à 2, avec des identités à 0 et ±∞. — Le régime est inversé dans les négatifs. — Les opérations ne fonctionnent pas comme pour les entiers signés en complément à 2. Par exemple, pour des fractions réelles : 5 7 3 + (− ) = (5.2) 4 8 8 , mais pour des Posit<6,1> : 0b010001 + 0b110001 = 0b000010 (5.3)

26 Département TIC, 27 juillet 2018

1 , qui vaut 64 en fraction réelle. Autrement dit, toutes les opérations ne sont pas faisable sans décodage préalable des informations que sont l’exposant issu du régime et du champs exposant, ainsi que des parties fractionnelles si présentes.

5.4.2.6 Méthodes de calcul La valeur mathématique d’un Posit quelconque se calcule comme suit :  0, p = 0..0b  ±∞, p = 10..0  b x = (−1)s · (2(2es))r · 2e · 1.f (5.4)  s (2es)r e  ⇐⇒ (−1) · 2 · 2 · 1.f , sinon  es  ⇐⇒ (−1)s · 22 r+e · 1.f avec s = signe, r = régime, e = exposant, f = partie fractionnelle et es = taille en bits d’exposant.

Il n’est pas envisageable d’effectuer une expansion totale des nombres lors des calculs, car la représentation est justement conçue pour compresser les données. En effet, la valeur expansée pourrait nécessiter un nombre excessif de bits (plusieurs centaines selon la taille du Posit), notamment avec les extrêma. Il est alors plus pratique de découper les opérations en sous-opérations effectuées sur les champs.

Pour des Posit de mêmes tailles, un développement mathématique permet de mettre en évidence la méthode à utiliser. Pour l’addition, on a :  ±∞, x = ±∞ ∨ x = ±∞  1 2 x1 + x2 = 0, x1, x2 = 0 (5.5) es es  s1 2 r1+e1 s2 2 r2+e2 ((−1) · 2 · 1.f1) + ((−1) · 2 · 1.f2), sinon Pour la soustraction, on a :  ±∞, x = ±∞ ∨ x = ±∞  1 2 x1 + x2 = 0, x1, x2 = 0 (5.6) es es  s1 2 r1+e1 s2 2 r2+e2 ((−1) · 2 · 1.f1) − ((−1) · 2 · 1.f2), sinon Pour la multiplication, on a :  ±∞, x = ±∞ ∨ x = ±∞  1 2  0, (x1 = 0 ∨ x2 = 0) ∧ x1, x2 6= ±∞  es es  s1 2 r1+e1 s2 2 r2+e2  ((−1) · 2 · 1.f1)((−1) · 2 · 1.f2) x1x2 = es es s1 s2 2 r1+e1 2 r2+e2  ⇐⇒ (−1) (−1) · 2 · 2 · 1.f1 · 1.f2  es es , sinon  s1+s2 2 r1+e1+2 r2+e2  ⇐⇒ (−1) · 2 · 1.f1 · 1.f2  es  s1+s2 2 (r1+r2)+(e1+e2)  ⇐⇒ (−1) · 2 · 1.f1 · 1.f2 (5.7)

27 Département TIC, 27 juillet 2018

Pour la division, on a :  ±∞, x = ±∞ ∨ x = 0  1 2  0, x2 = ±∞ ∧ x1 6= ±∞  s 2esr +e  (−1) 1 2 1 1 1.f1  s 2esr +e  (−1) 2 2 2 2 1.f2  s 2esr +e  (−1) 1 2 1 1 1.f1  ⇐⇒ s · 2esr +e ·  (−1) 2 2 2 2 1.f2 x  s 2esr e 1 (−1) 1 2 1 2 1 1.f1 = ⇐⇒ s · 2esr e · (5.8) (−1) 2 2 2 2 2 1.f2 x2 s 2esr e  (−1) 1 2 1 2 1 1.f1 , sinon  ⇐⇒ s · 2esr · e ·  (−1) 2 2 2 2 2 1.f2  2esr e  s1−s2 2 1 2 1 1.f1  ⇐⇒ (−1) · 2esr · e ·  2 2 2 2 1.f2  es  ⇐⇒ (−1)s1−s2 · 22 (r1−r2) · 2e1−e2 · 1.f1  1.f2  es  ⇐⇒ (−1)s1−s2 · 22 (r1−r2)+(e1−e2) · 1.f1 1.f2 En résumé, on a :

Opération signe régime exposant fraction + signe du plus grand en absolu maximum de magnitude maximum de magnitude + avec alignement − x < y maximum de magnitude maximum de magnitude − avec alignement × + + + × ÷ − − − ÷

À noter qu’il n’y a pas de simplification pour des additions de puissances d’exposants différents.

5.4.2.7 Algorithmes Les algorithmes ci-dessous sont simplifiés et ne montrent pas la gestion des cas limites, ni précisément comment gérer bit à bit l’encodage.

1 FONCTIONPURE decode (posit : POSIT)RETOURNE{BIT,ENTIER,ENTIER} VARIABLE negatif :BIT 3 VARIABLE regime, exposant , 5 fraction :ENTIER

7 negatif <- p[n]

9 SI negatif,ALORS posit <- COMPLEMENTADEUXDEp 11 FINSI

13 SI p[n-1]ESTNUL,ALORS regime <- NOMBREDE’0’ENTETEDE p[n-1 : 1] 15 exposant <- p[n-regime-2 : n-regime-2-es] fraction <- p[n-regime-2-es : 1] 17 exposant <- exposant - regime * 2^es SINON,ALORS 19 regime <- NOMBREDE’1’ENTETEDE p[n-1 : 1] exposant <- p[n-regime-2 : n-regime-2-es] 21 fraction <- p[n-regime-2-es : 1] exposant <- exposant + regime * 2^es 23 FINSI

25 AJOUTERBITIMPLICITEDE y.fraction

27 RETOURNER {negatif, exposant, fraction} FINFONCTION

FONCTIONPURE negation (p : POSIT)RETOURNE POSIT 2 RETOURNERCOMPLEMENTADEUXDEp FINFONCTION

28 Département TIC, 27 juillet 2018

1 FONCTIONPURE additionner (p1,p2 : POSIT)RETOURNE POSIT VARIABLE x, y, r : {negatif :BIT, exposant :ENTIER, fraction :ENTIER} 3 x <- decode(p1) 5 y <- decode(p2)

7 SI x.exposant PLUS GRAND y.exposant,ALORS r.exposant <- x.exposant 9 r.fraction <-DECALER y.fractionADROITEDE x.exposant - y.exposant r.fraction <- r.fraction + x.fraction 11 SINON,ALORS r.exposant <- y.exposant 13 r.fraction <-DECALER x.fractionADROITEDE y.exposant - x.exposant r.fraction <- r.fraction + y.fraction 15 FINSI

17 SIRETENUE,ALORS r.exposant <- r.exposant + 1 19 r.fraction <-DECALER r.fractionADROITEDE1 SINON 21 RETOURNER encode(r) 23 FINFONCTION

1 FONCTIONPURE soustraire (p1,p2 : POSIT)RETOURNE POSIT VARIABLE x, y, r : {negatif :BIT, exposant :ENTIER, fraction :ENTIER} 3 x <- decode(p1) 5 y <- decode(p2)

7 SI x.exposant PLUS GRAND y.exposant,ALORS r.exposant <- x.exposant 9 r.fraction <- -DECALER y.fractionADROITEDE x.exposant - y.exposant r.fraction <- r.fraction + x.fraction 11 SINON,ALORS r.exposant <- y.exposant 13 r.fraction <-DECALER x.fractionADROITEDE y.exposant - x.exposant r.fraction <- r.fraction - y.fraction 15 FINSI

17 zeros <- NOMBREDE’0’ENTETEDE r.fraction r.exposant <- r.exposant - zeros 19 r.fraction <-DECALER r.fractionAGAUCHEDE zeros

21 RETOURNER encode(r) FINFONCTION

FONCTIONPURE multiplier (p1,p2 : POSIT)RETOURNE POSIT 2 VARIABLE x, y, r : {negatif :BIT, exposant :ENTIER, fraction :ENTIER}

4 x <- decode(p1) y <- decode(p2) 6 r.negatif <- x.negatif XOR y.negatif 8 r.exposant <- x.exposant + y.exposant r.fraction <- x.fraction * y.fraction 10 RETOURNER encode(r) 12 FINFONCTION

FONCTIONPURE diviser (p1,p2 : POSIT)RETOURNE POSIT 2 VARIABLE x, y, r : {negatif :BIT, exposant :ENTIER, fraction :ENTIER}

4 x <- decode(p1) y <- decode(p2) 6 r.negatif <- x.negatif XOR y.negatif 8 r.exposant <- x.exposant - y.exposant r.fraction <- x.fraction / y.fraction 10 RETOURNER encode(r) 12 FINFONCTION

29 Département TIC, 27 juillet 2018

5.4.3 Seconde variante, le Valid Les Valids sont des Posits rigoureux. Ils utilisent une paire de Posit, avec un bit d’incertitude (ubit) appondu à chacun d’eux. Le fonctionnement est basé sur l’arithmétique d’intervalles.

5.4.3.1 Format Le format est simple, on utilise 2 Posits, agrémentés de bit d’incertitude en poids faible :

sign regime exponent fraction ubit sign regime exponent fraction ubit

s r⋯ r e1⋯ ees f1⋯ u s r⋯ r e1⋯ ees f1⋯ u

Lower tile Upper tile Figure 5.6 – Format des Valids[3]

5.5 Implémentations des Posits

5.5.1 Logicielles

Nom Auteur Licence Langage Unum Taille Universal Number Library LLNL LGPL C 1 ? terzerm/unum Marco Terzer MIT Java 1 32, 64, 128 Lombiq Arithmetics Lombiq Technologies Lombiq C# 1 ? pyunum Jeff Muizelaar N/A Python 1 variable cppunum2 Emanuele Ruffaldi N/A C++ 2 8 * N Pivot Unums Isaac Yonemoto MIT Julia 2 8 unumjl REX-Computing MIT Julia 2 ? Pnums Jason W. Merrill MIT Julia 2 3, 4, 8, 16 pyunum2 Emanuele Ruffaldi Apache2.0 Python 2 8 * N bfp Clément Guérin MIT C/C++ 3-posit variable Universal Number Arithmetic Posit Research MIT C++ 3-both variable C++ Posit implementation Emanuele Ruffaldi GPLv3.0 C++ 3-Posit 8, 10, 12 japaric/posit Jorge Aparicio MIT Rust 3-Posit variable sgpositpy SpeedGo Computing MIT Python 3-Posit variable HAST-136 Lombiq Technologies Lombiq C# 3-Posit <32,2> posit-javascript Siew Hoon Leong N/A JS 3-Posit 6,8,16,32, es=1..4 PySigmoid Ken Mercado MIT Python 3-Posit < ?, ?> SoftPosit Siew Hoon Leong N/A C++ 3-Posit <16,1> Diego Coelho GPLv3.0 Octave 3-Posit < ?, ?>

Table 5.4 – Liste non exhaustives d’implémentations logicielles

5.5.2 Matérielles (soft-core)

Nom Auteur Licence Langage Unum Unum_32bit_3_adder Jianyu Chen N/A Verilog Posit<32,3> Unum_32bit_3_multiplier Jianyu Chen N/A Verilog Posit<32,3> Unum_32bit_3_multiply_adder Jianyu Chen N/A Verilog Posit<32,3> Posit32-2-exact-multiply-accumulator Jianyu Chen N/A Verilog Posit<32,2> Posit-HDL-Arithmetic Manish Kumar Jaiswal BSD 3-Clause Verilog Posit< ?, ?>

Table 5.5 – Liste non exhaustives d’implémentations matérielles

30 Département TIC, 27 juillet 2018

5.5.3 Observations — Les implémentations logicielles sont souvent complexifiées à cause de la quantité de wrappers utilisés. L’implémentation la plus proche de la méthodologie utilisée dans GCC est la bfp. — Les implémentations disponibles ignore souvent les arrondis, ce qui engendre plus d’erreurs. — L’implémentation matérielle n’est pas conçu pour être scalable, mais quelques adaptation devraient pouvoir le permettre. En outre, cette implémentation ne comporte pas toutes les opérations possibles.

31 Chapitre 6 Réalisation du projet

6.1 Structure du projet

Dossier/ Fichier Contenu README.md Descriptif principal du projet (en anglais) LICENSE.md Licence logicielle (en anglais) cfg sauvegardes de configuration des dépendances dl sauvegarde de dépendances logicielle (archive) doc rapports, documents, ressources env dossier créer lors du setup du projet lib dépendances comme sous-modules git lib/benchmark sous-module, clone de Google Benchmark lib/cppunit sous-module, clone de CppUnit lib/bfp sous-module, clone d’une implémentation logicielle des Posits scripts scripts Bash et Tcl src sources des logiciels modifiés src/hdl premier draft (incomplet), d’une unité de traitement matérielle pour les Posits test sources des tests, avec Makefile test/wrappers couche d’adaptation C/C++ vers C++ pour les tests logiciels test/hdl premier draft de banc de test matériel pour les Posits

Table 6.1 – Arborescence grossière du projet

6.2 Licence logicielle

Tous les logiciels modifiés dans le cadre de ce projet sont sous licence logicielle libre, plus particulièrement différentes versions de ls GNU General Public License (GNU GPL). Comme ce projet se veut d’être un projet open source, celui-ci est sous le même type de licence, ici la GNU GPLv3.

Pour les autres logiciels, ceux-ci sont uniquement des outils qui ne font pas partie intégrante de ce projet.

6.3 Émulation logicielle floating-point dans GNU/Linux

L’émulation passe, soit par la GNU Toolchain qui s’occupe alors de générer un code spécifique pour le soft-float, soit par un support directement dans le noyau.

6.3.1 Du côté noyau Le support est valable uniquement lorsque les instructions matérielles dédiées ne sont pas reconnues. Il existe 2 supports possibles[28] à choix lors de la configuration du noyau : — Netwinder Floating Point Emulation (NWFPE) — Fast Floating Point Emulation (FastFPE), 3 à 5 fois plus rapide que NWFPE, mais produit des résultats moins stables.

6.3.2 Architectures supportées par la GNU Toolchain Dans la GNU Toolchain, toutes les architectures ne possèdent pas forcément le support pour l’émulation logicielle floating-point, qui est originellement dédié aux architecture dont certains processeurs ne possèdent pas de Floating-Point Unit (FPU). Autrement dit, l’architecture x86 et x86_64 n’ont pas d’options pour ce support, car les FPU sont intégrées depuis longtemps aux processeurs. Voici une liste non exhaustive d’architectures ayant droit à l’émulation :

32 Département TIC, 27 juillet 2018

— ARM (ARMv6M, ARMv7-a, ...) — ARC — MIPS — Nios II

6.4 Immersion dans la GNU Toolchain

6.4.1 Infrastructure 6.4.1.1 Pré-requis

Composant Description gmp GNU Multiple Precision Arithmetic Library mpfr bibliothèque GNU MPFR, basée sur GMP, mais avec arrondis corrects mpc bibliothèque GNU MPC, basée sur GNU MPFR, pour les nombres complexes isl bibliothèque de manipulation d’ensembles d’entiers contraints

Table 6.2 – Liste des pré-requis principaux de la GNU Toolchain

6.4.1.2 Composants

Composant Description GNU Binutils éditeur de lien (linker), assembleur, ... GGC ensemble de compilateurs GNU C Library implémentation GNU de la bibliothèque standard C GDB GNU Debugger Autotools GNU Build System, automatisation de configuration et compilation

Table 6.3 – Liste des composants principaux de la GNU Toolchain

6.4.1.3 Organisation des sources Les sources de la GNU Toolchain et plus particulièrement GCC respecte une arborescence récursive, où : — Le projet contient son propre dossier config. — Chaque module du projet peut contenir des sous-modules. — Chaque module du projet peut contenir un dossier config. — Un module correspond souvent à un exécutable ou une bibliothèque. Les dossier config contiennent des fichiers avec des directives génériques, ainsi que des dossiers de spécialisation par architectures.

33 Département TIC, 27 juillet 2018

6.4.1.4 Types de fichiers

Extension Description .S,.s Source assembleur .h,.c,.cpp En-tête et source C/C++ .md Machine Description (pas Markdown) .opt Déclaration d’options de compilation .gmo Fichier de langue pour GCC .texi,.tex,.xml Source pour la documentation .ver Version d’API, de bibliothèques, etc .tpl Script template pour Autogen 5 .tgt Shell script pour la configuration .ml Source OCaml, pour générer des pattern ARM LDM/STM

Table 6.4 – Type de sources dans GCC

6.4.2 Fonctionnement de GCC 6.4.2.1 Front-end Le rôle d’un front-end est de transformer le code d’un langage particulier vers des représentations intermédiaires abstraites, comme GENERIC ou GIMPLE, qui sont plus faciles à manipuler lors des optimisations.

6.4.2.2 Back-end Le rôle d’un back-end est de convertir les représentations intermédiaires abstraite haut-niveau vers une représentation bas-niveau tel que Register Transfer Language (RTL). Le back-end possède des informations avancées sur la cible, afin d’optimiser les instructions produites. Pour ce faire, le back-end est notamment constitué de : — Fichiers de type Machine Description (.md), qui contient une masse d’information sur les instructions, dont les contraintes, etc. — Fichiers de type Option (.opt), qui déclare les options en ligne de commande ainsi que les valeurs associées dans le programme. — Fichiers en-tête C avec les déclarations des types de données des options, comme des énumérations (cas de -mfloat-abi). — Fichiers source C contenant des fonctions appelées lors de l’exécution de GCC, comme la fonction arm_init_libfuncs qui indique les routines à appeler pour le soft-float.

6.4.3 Options floating-point à la compilation d’une application Les options sont spécifiques à l’architecture supportée. Pour les architectures ARM, le type de support peut-être choisi grâce à l’option -mfloat-abi=, avec les valeurs [29]:

Valeur Description hard Utilise les instructions dédiées aux opérations floating-point soft Utilise un ensemble de routines d’émulation softfp Utilise les instructions matérielles dédiées avec la convention d’appel des soft-float

Des alias existent, notamment -mfloat-hard et -mfloat-soft. Les soft-float et hard-float ne sont pas compatibles à l’édition de liens, notamment au niveau des bibliothèques (à chargement dynamique ou non). Cela implique que toutes les dépendances doivent utiliser les mêmes conventions d’Application Binary Interface (ABI). L’implémentation soft-float n’est pas disponible pour tous les processeurs cibles.

Les routines d’émulation[30] sont présentes dans le dossier libgcc de GCC.

34 Département TIC, 27 juillet 2018

6.4.3.1 ARM ABI s : OABI vs EABI La GNU Toolchain étant ancienne, différente ABI ont été utilisées. L’ABI utilisée depuis GCC 5 est l’Embedded ABI (EABI), alors que GCC utilisait auparavant une autre ABI, surnommée Old-ABI (OABI)[31][32].

Alors que l’EABI permet d’utiliser des routines user-space pour le soft-float, lOABI présumait que des Floating-Point Unit étaient présentes. Autrement dit, pour les plate-formes qui n’en disposaient pas, une exception était levée au niveau du noyau, avec un appel à des routines pour émuler l’instruction.

6.4.3.2 Usage des ressources matérielles L’émulation requiert de se passer entièrement de Floating-Point Unit, quelles soient sur co-processeur ou non. Les algorithmes doivent alors traiter le floating-point par le biais d’instructions sur des entiers. Le format ne change pas, mais la donnée est chargée dans un registre dédié aux entiers plutôt que dans un registre spécial pour floating-point. Par exemple, sur un processeur ARM Cortex-A9 MPCore qui utilise l’ISA ARMv7-a, les registres r0 à r12 seront utilisés plutôt que les registre s0 à s31 ou d0 à d31. Ceci explique pourquoi les conventions soft et hard ne sont pas compatibles.

6.4.3.3 Lien dans les applications Pour une application avec l’ABI soft, les routines sont directement intégrées à l’exécutable résultant de la compilation. Ces routines ne sont pas compilée en même temps que l’application, mais ont été pré-compilée dans une archive objet de la libgcc. Les routines sont alors identiques, quelque soit les optimisations choisies. GCC est susceptible d’intégrer ces routines directement aux applications selon les besoins d’après la configuration de la toolchain et les options de compilation.

6.4.3.4 Implémentations des routines Dans GCC, il existe plusieurs implémentations du soft-float. La première, générique et portable, est écrite en C grâce à un ensemble de macros élaborées. Cette implémentation est une copie d’une partie de la GNU C Library et sa localisation est libgcc/soft-fp. L’implémentation générique est utilisée uniquement pour l’architecture ARMv6M

Les autres implémentations sont spécialisées et optimisées pour le processeur cible. Elles sont écrites directement en assembleur, et se trouvent dans libgcc/config/, comme par exemple libgcc/config/arm.

6.5 Mécanismes à gérer

Une intégration complète demande de gérer : — Les conversions de type. — L’adaptation des constantes : — soit par conversion du standard IEEE Std 754-2008 vers Unum. — soit lors de la conversion texte vers binaire par le compilateur. — La conversion textuelle, en modifiant les algorithmes de la libc pour les format %f, %e et %g. Potentiellement, l’impact doit aussi considérer : — Les optimisations du compilateur. — La gestion des exceptions liées au instructions dédiées pour le floating-point.

35 Département TIC, 27 juillet 2018

6.6 Considérations sur le développement

Afin de développer correctement une nouvelle solution, certains critères sont à considérer précautionneusement. En anticipation, doit être pris en compte : — Les conventions de codage et de nomenclature, afin de faciliter l’intégration. — L’architecture logicielle, dont les concepts utilisés devraient en principe être similaires au projet cible.

6.6.1 Interventions dans les sources Afin de s’intégrer à un projet de l’ampleur de GCC, il convient de modifier les sources du projet au minimum. Par contre, ajouter de nouveaux fichiers qui ne sont pas suivis (trackés) dans l’arborescence permet de se greffer simplement sans polluer inutilement les sources déjà présentes.

6.6.2 Version de GCC Le projet GNU maintient en parallèle 3 versions de GCC en plus de la version de développement. Actuellement, les versions maintenues sont 8.1, 7.3 et 6.4. La version de développement est la 9.0.

Comme il faut généralement un certains temps pour qu’une nouvelle version soit largement déployée, il est préférable de se baser sur l’une des version de maintenance. La version ne doit pas être très ancienne afin d’éviter un abandon prochain du support et de l’usage. En outre, le support pour le soft-float est plus complet sur les versions plus récentes.

Les versions 6.4 et inférieures sont donc à éviter. La version 7.3.1 se trouve être la dernière version stable de Linaro GCC maintenu par l’association Linaro, dévolue à l’amélioration du support ARM sur GNU/Linux. Cette version ou une version proche de celle-ci est alors appropriée.

6.7 Méthodes d’intégration

6.7.1 Aspect fonctionnel Afin de choisir la méthode d’intégration la plus avantageuse, on peut comparer : — Le bénéfice pour l’utilisateur — La complexité de la méthode — L’impact sur les sources du projet existant — Les risques

6.7.1.1 Bénéfice pour l’utilisateur L’intérêt principal pour un utilisateur est la possibilité d’utiliser une fonctionnalité, sans pour autant y être obligé. Autrement dit, la fonctionnalité à intégrer doit s’ajouter et non pas supplanter une fonctionnalité existante. Dans ce projet, l’utilisateur doit pouvoir utiliser les Posits, mais doit également pouvoir continuer à utiliser le standard , que ce soit l’accélération matérielle ou l’émulation logicielle.

6.7.2 Portabilité Sur le principe, les Posits logiciels sont utilisables sur n’importe quelle architecture matérielle qui supporte les opération arithmétiques et logiques sur les entiers non signés et signés.

36 Département TIC, 27 juillet 2018

6.7.2.1 Types entiers natifs Les problèmes de portabilité commence avec les tailles des types entiers supportés par la cible, car la cible possède rarement des entiers de taille 128 ou 256 bits et sur certaines plate-forme, même les entiers 64 bits peuvent être absents. En outre, la représentation des nombres signé doit également être prise en compte lors de l’implémentation des algorithmes.

6.7.2.2 Support de la cible Dans GCC, le choix du support soft-float n’est pas disponible pour toutes les cibles. De plus, chaque cible possède une implémentation spécifique des routines, associée avec une configuration dédiée. Ceci implique que : — L’extension du support soft-float d’origine ne fonctionne que certaines cibles. — Les sources spécifiques à chaque cible doivent être modifiées pour autoriser dynamiquement le choix de l’alternative. — La configuration de chaque cible doit être modifiée afin d’ajouter l’option supplémentaire. — Le support des Posits pour d’autres cibles que celles supportant le soft-float peut nécessiter de profond changement dans l’émetteur d’instruction.

6.7.3 Remplacement Le remplacement des soft-float nécessite : — soit de générer des routines spécifiques à chaque cible. — soit de modifier les routines génériques, et de forcer l’usage de ces routines quelque soit la cible. Ceci revient à modifier la configuration utilisée lors du build de la toolchain. À noter que cette méthode permet de générer une toolchain supportant les Posits, mais qui en revanche ne supporte plus le soft-float standard. De plus, afin de minimiser la modification des sources, la structure des algorithmes génériques pour les Posits doit s’approcher au mieux des algorithmes soft-float, ce qui peut être excessivement contraignant. En effet, certains des mécanismes des Posits sont plus légers que ceux de l’implémentation générique des soft-float.

6.7.3.1 Approche générique Le format Posit est déclaré dans un fichier en-tête, et une interface de base faite de macros est définie. Cette interface de base permet de construire des macros plus complexes que l’on peut faire correspondre à des macros déjà existante, afin de les remplacer. Il suffit alors de remplacer le/les en-têtes d’origine par le nouvel en-tête partout où celui-ci doit remplacer le standard.

6.7.4 Ajout L’ajout à côté des soft-float nécessite au minimum de : — créer de nouvelles routines à ajouter à la libgcc. — ajouter un script Make pour traiter les nouvelles routines. — modifier la config.host de libgcc, afin de référencer le nouveau script pour chaque cible pouvant supporter les Posits logiciels. — modifier la liste des options pour chaque cible concernée. — modifier les sources où la nouvelle option doit être prise en compte.

37 Département TIC, 27 juillet 2018

6.7.5 Principes algorithmiques de l’implémentation générique Des unions entre un floating-point et une structure sont utilisées, afin d’accéder aux données : — soit en tant que floating-point. — soit en tant qu’entier. — soit par morceaux entier, dans le cas où le plus grand entier disponible est plus petit que la taille du format à traiter. Les routines fonctionnent toutes sur une méthodologie similaire : 1. Configuration des exceptions 2. Déclaration des variables locales 3. Initialisation du mode d’arrondi 4. Unpacking des opérandes vers les variables locales 5. Exécution de l’opération avec stockage dans une variable de résultat 6. Packing du résultat 7. Traitement des exceptions 8. Retourne le résultat empaqueté

6.8 Mise en place des Posits dans la GNU Toolchain

6.8.1 Méthode de mise en place Finalement, la solution qui semble la plus adaptée est l’ajout. Une nouvelle valeur possible pour l’option -mfloat-abi est ajoutée, la valeur posit. L’alias -msoft-posit est également créé.

Les routines à définir sont développées dans le but d’être avant tout portable sur n’importe quelle architecture. Une fois, ces algorithmes validés, il sera envisageable d’en faire des versions optimisées spécifiques à chaque cible. Les algorithmes reprennent les mêmes principes que l’implémentation générique des soft-float. Cependant, il y a des divergences, car certaines opérations ne nécessite pas de décodage des données, notamment, le test d’égalité ou encore la négation (obtention de l’opposé, opérateur unaire -).

6.8.2 Modification de GCC Ici, les fichiers modifiés sont :

Fichier/Dossier Description libgcc/unum-fp algorithmes génériques, copie modifiée de libgcc/soft-fp libgcc/config/t-unumfp directives GNU Make, copie modifiée de libgcc/config/t-softfp libgcc/config.host ajout des inclusion de t-unumfp par association à t-softfp gcc/config/arm/arm.opt ajout des des déclarations des nouvelles options gcc/config/arm/arm-opts.h ajout de la nouvelle valeur ARM_FLOAT_ABI_POSIT à l’enum float_abi_type gcc/config/arm/arm.h modification des macros de test d’ABI utilisée gcc/config/arm/arm.c ajout de la sélection entre les routines soft-float et les routines pour Posits

Table 6.5 – Liste des sources modifiées dans GCC

38 Département TIC, 27 juillet 2018

6.8.3 Modification de Binutils Comme l’outil GNU Assembly fait partie de Binutils, il faut modifier celui-ci afin d’enregistrer la nouvelle option comme étant une ABI valide. Voici les fichiers touchés :

Fichier/Dossier Description ajout de la nouvelle valeur ARM_FLOAT_ABI_POSIT à l’enum binutils-unum-2.30/gas/config/tc-arm.c float_abi_type, de la valeur texte posit comme nouvelle option

Table 6.6 – Liste des sources modifiées dans Binutils

6.9 Choix de la cible et de l’environnement hôte

6.9.1 Environnement cible 6.9.1.1 Plate-formes Lesoft-float est principalement disponible sur les plate-formes ARM, qui sont parmi les plus répandues. De plus, les SoC+FPGA d’Altera et Xilinx utilisent majoritairement des processeurs ARM.

6.9.1.2 Système d’exploitation L’intégration vise GNU/Linux. Autrement dit, le système d’exploitation peut être : — Un GNU/Linux épurée, juste le noyau et le système de fichiers initial. — Une distribution GNU/Linux, telle que Lubuntu, souvent portée pour les plate-formes embarquées. Une distribution offre alors un déploiement logiciel simplifié. À noter toutefois que la GNU Toolchain ne se limite pas à GNU/Linux et peut également être utilisée sur d’autres systèmes, notamment ceux de la famille BSD (FreeBSD, ...).

6.9.2 Outils de développement Comme l’intégration vise GNU/Linux comme finalité, il est préférable d’utiliser une distribution GNU/Linux sur le ou les machines hôte pour le développement. Ubuntu étant une distribution stable, répandue, avec des logiciels relativement récents et un support conséquent, celle-ci est parfaitement adaptée.

6.9.2.1 Moteurs de production La génération des outils de cross-compilation peut être faite de plusieurs manières, selon le système de la machine de développement. On notera toutefois un net avantage à utiliser des outils d’automation de création d’environnement et de système de base, tels que : — crosstool-NG — Buildroot — Yocto — OpenEmbedded Pour ce projet, Buildroot 2018.02.3 est utilisé. L’outil crosstool-NG a été envisagé, mais celui-ci supporte GCC 6.3.0 comme version la plus récente, alors que Buildroot supporte GCC 7.3.x, une version proche de la dernière de Linaro GCC.

39 Département TIC, 27 juillet 2018

6.9.2.2 Outils d’analyse

Nom Usage grep Recherche de texte dans les sources et builds de GCC find Localisation de fichiers dans les builds de GCC readelf Voir l’architecture cible et les symboles des exécutables objdump Voir l’assembleur des exécutables strace Voir les appels systèmes faits par une application opensnoop Script de perf-tools qui monitore les ouvertures de fichiers

40 Chapitre 7 Tests

7.1 Méthodologie

À moins que l’ensemble des tests soit exhaustif, les tests ne prouvent pas le bon fonctionnement d’une solution, mais il est tout de même préférable de prouver au moins le bon fonctionnement de celle-ci pour un nombre cas connus et judicieusement choisis, afin que les cas non testés soient considérés fonctionnels grâce au raisonnement par récurrence.

7.1.1 Types de tests Il existe de nombreuses manières de tester une solution, quelle soit logicielle ou matérielle. Le choix des types de tests effectués dépend de la criticité de la fonctionnalité à tester. Voici quelque types tests : — Test exhaustif — Test formel — Test unitaire — Test fonctionnel — Test comparatif — Test de performance (Benchmarking)

7.1.2 Tailles de Posits Dans l’idéal, les Posit doivent être fonctionnels pour des tailles équivalentes à celles supportées pour le standard , définit 5 tailles que sont 16, 32, 64, 128, et finalement 256 bits. Des Posits de même taille avec des intervalles dynamiques les plus proches de ceux du standard doivent alors être testés, afin que les éventuelles comparaisons avec celui-ci soient pertinentes.

7.1.3 Ressources de tests — Implémentations existantes comme base de comparaison — Frameworks de développement de tests, tels que CppUnit ou GoogleBenchmark. — Programmes de benchmarking, comme LINPACK.

7.1.4 Facteurs limitants — Un test exhaustif nécessite de tester toutes les combinaisons d’opérande pour toutes les fonctions à vérifier. La taille de Posit peut faire exploser le nombre de cas à tester. Par exemple une addition de 2 Posits 16 bits prend 232 = 4294967296 combinaisons distinctes, soit plus de 4 milliards de tests. — Pour des plate-formes ARM, GCC version 7.3.0 supporte le soft-float uniquement pour des tailles de 32, 64 et parfois 128 bits. — Les routines logicielles se comportent différemment selon les tailles de Posits. Autrement dit, vérifier les algorithmes pour une taille ne permet pas de déduire que les algorithmes fonctionnent pour d’autres tailles. — L’ensemble des implémentations existantes de Posit ne comporte pas des implémentations équivalentes pour chaque taille de Posit souhaitées. — Les frameworks de test et les implémentations existantes de Posit ne sont pas nécessairement portées sur toutes les plate-formes. — Les implémentations existantes de Posit ne sont pas garanties libres de tout bug. — Des tests entre plate-formes différentes nécessitent des échanges de données binaires, avec la prise en compte de l’endianness.

41 Département TIC, 27 juillet 2018

7.1.5 Choix de la batterie de tests Comme les tailles de Posits vont de 16 à 256 bits et que plus de 80 routines sont à tester, un test exhaustif n’est envisageable pour cause de durée de test trop longue. Il convient alors de tester les cas limites pour chaque taille, ainsi que quelques centaines ou milliers de cas non limites choisis au hasard, mais si possible distribués uniformément.

7.1.5.1 Tests unitaires Les tests unitaires sont délicats à mettre au point, dans la mesure où il servent à tester la robustesse des implémentations. Les tests mis en place ici servent à : — Vérifier que les opérations et fonctions de base se comportent une à une correctement. — Vérifier qu’une implémentation est cohérente avec elle-même. — Vérifier que le comportement d’une implémentation est équivalent à celui d’une autre implémentation.

7.1.5.2 Tests fonctionnels Les tests fonctionnels sont les tests finaux et également les plus important, car il permettent de vérifier que le logiciel fonctionne dans son ensemble, lors de cas d’usage. Ici, c’est la construction et l’utilisation de la toolchain personnalisée qui fait office de test.

7.1.5.3 Tests de performance Ici, deux méthodes de tests sont appliquées. La première utilise des tests simples, où chaque fonction est testée séparément, par une répétition de la fonction jusqu’à épuisement du temps (timeout). La seconde méthode utilise de petit logiciel de tests pré-existants, mais éprouvés et couramment utilisés.

7.1.6 Choix des plate-formes de test Différentes plate-forme sont utilisée. Tout d’abord, les algorithmes génériques sont testés localement sur la machine hôte. Une fois le comportement vérifié, les algorithmes sont testés sur la machine cible. En effet, d’une architecture à l’autre, le comportement des algorithmes peut changer, notamment à cause de différences matérielles qui impactent la portabilité.

7.2 Tests logiciels

7.2.1 Wrappers Afin de pouvoir interfacer plusieurs implémentations logicielles différentes des Posits, des classes enveloppes ou wrappers ont été mises en place. Ceci permet alors de définir une même interface avec les différentes implémentation, autant pour construire les données que pour utiliser les opérateurs.

Ensuite, ces wrappers sont instanciés lorsque nécessaire, pour être fournis aux classes de test, soit unitaire, soit de mesure de performance (benchmarking)

7.2.2 Bancs de test Le banc de test est écrit en C++, avec l’aide du framework CppUnit. Celui-ci permet une grande automatisation des tests unitaires, avec une indication de tests échoués et un bilan final de test. Les tests réalisés ici se déclinent en 2 moutures, les tests de cohérence (ClosureFixture) et les tests de comparaison d’implémentation (ComparisonFixture).

42 Département TIC, 27 juillet 2018

7.2.3 Benchmarking Ici, les outils utilisés sont : — Le framework Google Benchmark. — Le programme de test LINPACK, la version révisée d’octobre 1994. Ce programme est légèrement modifié ici, afin de pouvoir configurer le type de floating-point. Les tests réalisés à l’aide de Google Benchmark sont complémentaires aux tests unitaires et ne contrôlent par conséquent pas les résultats des opérations.

7.3 Améliorations et tests manquants

Les tests effectués ici possèdent 4 failles principales : — Les tests sont orientés sur des opérations isolées et non sur des combinaisons. — Les tests ne comparent pas assez d’implémentations entre elles. — Les valeurs générées pour les tests sont loin d’être adaptées. La génération des valeurs est tout particulièrement délicate pour les tests de cohérence, car une valeur de référence doit être émise. Un générateur est en cours de réalisation, mais il est encore incomplet. — Il n’existe pas de procédure pour les tests fonctionnels. En outre, l’implémentation de certaines classes pourrait conduire à des défaillances en cas d’usage non prévu, notamment parce que les paramètres des template ne sont pas contraints.

7.4 Résultats des tests

— Les tests unitaires ne passent pas tous en entier, il reste encore des bugs à retirer, autant du côté des tests que du côté de l’implémentation des Posits. — Les performances sont moins bonne que d’autres implémentations, comme la bfp. Ceci peut s’expliquer par le fait que les algorithmes sont complexifiés avec les macros et que ma maîtrise du langage C n’est pas encore optimale.

7.5 Hardware de test

7.5.1 Machines hôtes

Propriété Description Modèle MacBookPro 11,5 (15", mid-2015) OS macOS High Sierra 10.13.3 (17D102) CPU Intel(R) Core(TM) i7-4870HQ @ 2.5GHz GPU AMD Radeon R9 M370X 2 Go, Intel Iris Pro 1536 MB Mémoire 2x8GB DDR3L @ 1600MHz VM-dev Ubuntu 16.04.4 LTS, 4GB Memory

Propriété Description Modèle Dell OptiPlex 9020 OS Ubuntu 16.04.4 LTS Noyau Linux 4.13.0-45-generic SMP x86_64 CPU Intel(R) Core(TM) i7-4790 CPU @ 3.60GHz Mémoire 2x8GB DDR3 @ 1600MHz

43 Département TIC, 27 juillet 2018

7.5.2 Plate-formes cibles (embarquées)

Propriété Description Modèle Terasic DE1-SoC revision F OS Linux 4.15 CPU 800MHz Dual-core ARM Cortex-A9 MPCore Mémoire 1GB DDR3 SDRAM FPGA Altera Cyclone R V SE 5CSEMA5F31C6N

44 Chapitre 8 Conclusion

8.1 Résultats obtenus

Compte tenu des bugs encore présents, les tests ne sont pas totalement concluants. Pour l’instant, voilà ce qui peut être dit : — Pour les familles de processeur ARM pour lesquelles la GNU Toolchain accepte le soft-float, les options -mfloat-abi=posit et -msoft-posit ont été ajoutées avec succès. — Le support des Posits se limite à la version 32 bits. Un effort de portabilité doit être fourni pour les versions 64 et 128 bits, avec une infrastructure déjà présente, mais à consolider. Le soft-float 16 et 256 bits n’est pas supporté dans GCC 7.3.0, mais des éléments structuraux sont déjà présents, ce qui laisse présager un support possible, moyennant force de travail. — Les constantes incrustées dans les programmes ne sont pas encore encodées sous forme de Posits. — Les performances peuvent encore être améliorées.

8.2 Gestion du temps

Comme ce travail est principalement un travail de recherche qui se déroule en parallèle d’autres travaux, l’orientation a été discutée de plusieurs fois. En outre, la complexité des sources de la GNU Toolchain étant supérieure à ce que j’avais imaginé, ma planification était trop optimiste.

8.2.1 Quelles auraient été les mesures à prendre ? La phase d’étude aurait dû être plus structurée, avec : — (Fait au trois-quarts) Établir l’intérêt théorique de l’alternative, avec critiques à l’appui et vis-à-vis des autres alternative. — Établir où l’intérêt est le plus fort parmi les logiciels libre, pas seulement théoriquement, mais avec des statistiques à l’appui. — Soigneusement étudier la structure de l’écosystème GNU/Linux, avec une estimation du taux de faisabilité dans le temps imparti.

8.3 Difficultés rencontrées

Ce travail nécessite de maîtriser : — L’analyse numérique. — L’encodage des symboles. — La programmation bas-niveau, avec des considérations matérielles et de portabilité. — L’écosystème logiciel des systèmes GNU/Linux. — La structure de logiciels complexes et anciens. Les difficultés issues de ces pré-requis sont : — La vaste étendue de logiciels à explorer, avec une concentration sur la GNU Toolchain et le noyau Linux. — L’élaboration des algorithmes lorsque certaines opérations de base ne peuvent plus se faire de manière atomique. — Gérer la portabilité des algorithmes, sachant que :

45 Département TIC, 27 juillet 2018

— Le standard C possède des cas de comportements indéfinis (undefined behavior) — Les tailles de type entier ne sont pas figées par le standard C. — Le comportement des opérations sur les entiers n’est pas toujours garanti, comme pour la différenciation du décalage logique ou arithmétique. — Trouver toutes les informations nécessaires aux modifications à effectuer pour ajouter ou étendre une fonctionnalité d’un logiciel. Par exemple, la documentation offre un aperçu général du fonctionnement, mais les détails internes de chaque fonctionnalité doivent être trouvés au travers des sources du logiciel.

8.4 À poursuivre dans le futur

Ce projet se déroule en concurrence avec l’établissement du standard. Celui-ci peut mettre du temps à être approuvé, mais rien n’empêche d’approfondir les recherches et de paver la route vers une intégration logicielle et matérielle complète. Le travail déjà effectué montre qu’il est possible moyennant exploration approfondie d’intégrer non seulement les Posits, mais tout autre alternative dans les outils courants de développement utilisés sous GNU/Linux.

Autrement dit, ce projet est destiné à évoluer pour peu qu’une équipe travaille dessus. Les prochains objectifs à remplir sont : — Compléter les routines encore non fonctionnelles. — Modifier les algorithmes de conversion des constantes à la compilation. — Finir l’automation des procédures et la documentation — Étendre le support des Posits logiciels à toutes les plate-formes. — Activer la demi-précision logicielle, en prenant en compte les standards des langages de programmation. — Créer un accélérateur sur FPGA, soit intégré à un (co-)processeur soft-core comme le NiosII, soit intégré en tant que coprocesseur dédié.

46 Glossaire

ABI Une Application Binary Interface (ABI) est une interface de logicielle entre composants logiciels distincts, comme entre un système d’exploitation et une application (des appels de fonction ou des appels systèmes par exemple). . 31, 32, 43 API Une Application Programming Interface (API) est une interface de logicielle dédiée aux programmeurs. Une API fourni un ensemble de fonctionnalités de base et même des extensions permettant de facilité le développement de logiciels. . 43

ELF L’Executable Linkable Format ou ELF est un format d’exécutable permettant le chargement dynamique du programme et de ses dépendances. Le format possède alors de nombreuse informations en plus du code machines. . 43, 47

floating-point Ce terme signifie virgule flottante, en se référent aux nombres qui utilise une précision variable au cours du temps, comme pour la notation scientifique. .8,9, 32, 35, 43

LLVM Low Level Virtual Machine ou LLVM est une infrastructure comportant des chaînes de compilation ainsi que des outils d’analyse dynamique de programmes. . 43 look-up tables Les tables de correspondances ou textitlook-up tables (LUT) sont des éléments permettant l’association de valeurs telle une fonction, avec une mise en oeuvre sous forme de table de vérité, mémorisée ou figée matériellement. . 19, 20, 43 overflow Le dépassement de capacité ou overflow est un phénomène qui survient lorsque le résultat correct est trop grand par rapport aux limites de la représentation utilisée. Le résultat réellement obtenu est erroné, par rapport au résultat mathématique. . 17, 43 toolchain Une toolchain ou chaîne de compilation est une collection d’outils impliqués dans la compilation d’un programme pour un processeur donné.. 18, 43 underflow Le soupassement de capacité ou underflow est un phénomène qui survient lorsqu’un résultat correct non nul est trop petit pour être contenu dans les limites de la représentation utilisée, comme cela peut être le cas dans le standard IEEE Std 754-2008.. 17, 43 userspace Le userspace désigne l’environnement d’exécution au-dessus du système d’exploitation. . 43 wrappers Une enveloppe ou wrapper est une couche logicielle d’adaptation. Elle cache certains mécanismes à la vue du programmeur tout en fournissant une interface d’utilisation. . 28, 43

47 Bibliographie

[1] John L. Gustafson. THE END of ERROR - Unum Computing. Chapman & Hall/CRC Computational Science, 2015. [2] John L. Gustafson. A radical approach to computation with real numbers. http://www. johngustafson.net/pubs/RadicalApproach.pdf, 2016. [3] John L. Gustafson. Posit arithmetic. https://posithub.org/docs/Posits4.pdf, 10 2017. [4] John F. Wakerly. Digital Design - Principles & Practices. Prentice Hall, Upper Saddle River, NJ 07458, 3rd edition, 1999. [5] Wikimedia Commons contributors. Signed number representations. https://en.wikipedia.org/ w/index.php?title=Signed_number_representations&oldid=847859016, 2018. [Online ; accessed 27-July-2018]. [6] Wikipedia contributors. — wikipedia, the free encyclopedia. https: //en.wikipedia.org/w/index.php?title=Interval_arithmetic&oldid=846709196, 2018. [Online ; accessed 24-July-2018]. [7] IEEE Computer Society. Ieee standard for interval arithmetic. Technical Report IEEE Std 1788-2015, IEEE Computer Society, 06 2015. [8] Wikipedia contributors. Real projective line — wikipedia, the free encyclopedia. https: //en.wikipedia.org/w/index.php?title=Real_projective_line&oldid=836030884, 2018. [Online ; accessed 24-July-2018]. [9] Wikimedia Commons contributors. Illustration of real projective line. https://commons. wikimedia.org/w/index.php?title=File:Real_projective_line.svg&oldid=260092011, 2018. [Online ; accessed 24-July-2018]. [10] Wikipedia contributors. Arbitrary-precision arithmetic — wikipedia, the free encyclopedia. https://en.wikipedia.org/w/index.php?title=Arbitrary-precision_arithmetic& oldid=847217818, 2018. [Online ; accessed 24-July-2018]. [11] Robert Morris. Tapered floating point : A new floating-point representation. Technical report, Bell Telephone Laboratories, Inc., 1971. [12] Wikipedia contributors. Tapered floating point — wikipedia, the free encyclopedia. https:// en.wikipedia.org/w/index.php?title=Tapered_floating_point&oldid=850239451, 2018. [Online ; accessed 24-July-2018]. [13] Nathan Whitehead and Alex Fit-Florea. Precision and performance : Floating point and compliance for nvidia gpus. Technical Report TB-06711-001_v9.2, NVIDIA Corporation, 05 2018. [14] Wikipedia contributors. Karlsruhe accurate arithmetic — wikipedia, the free encyclopedia. https://en.wikipedia.org/w/index.php?title=Karlsruhe_Accurate_Arithmetic& oldid=791038733, 2017. [Online ; accessed 2-March-2018]. [15] P. J. W. RAYNER N. G. KINGSBURY. Digital filtering using logarithmic arithmetic. Electronics Letters, 7 :56–58, 01 1971. [16] Wikipedia contributors. Logarithmic number system — wikipedia, the free encyclopedia. https: //en.wikipedia.org/w/index.php?title=Logarithmic_number_system&oldid=815720880, 2018. [Online ; accessed 05-July-2018]. [17] Wikipedia contributors. Elias delta coding — wikipedia, the free encyclopedia. https://en. wikipedia.org/w/index.php?title=Elias_delta_coding&oldid=831014035, 2018. [Online ; accessed 05-July-2018].

48 Département TIC, 27 juillet 2018

[18] Wikipedia contributors. Elias gamma coding — wikipedia, the free encyclopedia. https://en. wikipedia.org/w/index.php?title=Elias_gamma_coding&oldid=638126020, 2018. [Online ; accessed 05-July-2018]. [19] Wikipedia contributors. Elias omega coding — wikipedia, the free encyclopedia. https://en. wikipedia.org/w/index.php?title=Elias_omega_coding&oldid=807741947, 2018. [Online ; accessed 05-July-2018]. [20] Hitachi Ltd. Kokubunji Tokyo 185 Japan Hozumi HAMADA, Central Research Laboratory. Urr : Universal representation of real numbers. New Generation Computing, 1983. [21] HAMADA Hozumi. A new real number representation and its operation. Technical report, Central Research Laboratory, HitachiLtd., 1987. [22] Isaac Yonemoto John L. Gustafson. Beating floating point at its own game : Posit arithmetic. http://www.johngustafson.net/pdfs/BeatingFloatingPoint.pdf, 2016. [23] Ignaz Kohlbecker. The slide number format. https://posithub.org/conga/2018/docs/ 6-Ignaz-Kohlbecker.pdf, 03 2018. [24] Jeff Hittinger Peter Lindstrom, Scott Lloyd. Universal coding of the reals : Alternatives to ieee floating point. https://posithub.org/conga/2018/docs/1-Peter-Lindstrom.pdf, 03 2018. [25] Prof. William Kahan. Commentary on the end of error - unum computing. https://people.eecs. berkeley.edu/~wkahan/EndErErs.pdf, 07 2015. [26] Prof. William Kahan. Comments on sorn arithmetic. https://people.eecs.berkeley.edu/ ~wkahan/SORNers.pdf, 07 2016. [27] Florent de Dinechin Andrea Bocco, Yves Durand. Hardware support for unum floating point arithmetic. Technical report, CEA-LETI, INSA-Lyon, 2017. [28] http ://linux 7110.sourceforge.net/. 22. floating point emulation notes. http://linux-7110. sourceforge.net/howtos/netbook_new/x1114.htm, 2018. [Online ; accessed 24-July-2018]. [29] GNU Compiler Collection Project. 3.18.4 arm options. https://gcc.gnu.org/onlinedocs/gcc/ ARM-Options.html, 2018. [Online ; accessed 21-March-2018]. [30] GNU Compiler Collection Project. (internals) 4.2 routines for floating point emulation. https: //gcc.gnu.org/onlinedocs/gccint/Soft-float-library-routines.html, 2018. [Online ; accessed 21-March-2018]. [31] Inc. Technologic Systems. Eabi vs oabi. https://wiki.embeddedarm.com/wiki/EABI_vs_OABI, 2018. [Online ; accessed 24-July-2018]. [32] Murat Demirten. What is the difference in toolchains named arm oabi and eabi ? https:// linux-tips.com/t/what-is-the-difference-in-toolchains-named-arm-oabi-and-eabi/ 67, 2018. [Online ; accessed 24-July-2018]. [33] John L. Gustafson. Unleashed computing : The need to right-size precision to save energy, bandwidth, storage, and electrical power. http://www.johngustafson.net/presentations/ Right-SizingPrecision1.pdf, 2016. [34] John L. Gustafson. An energy-efficient and massively parallel approach to valid numerics. http: //www.johngustafson.net/presentations/UnumArithmetic-ICRARseminar.pdf, 06 2016. [35] John L. Gustafson. A radical approach to computation with real numbers (unums 2.0). http: //www.johngustafson.net/presentations/Unums2.0.pptx, 06 2016. [36] John L. Gustafson. The great debate : Unum arithmetic position statement. http://arith23. gforge.inria.fr/slides/Gustafson.pdf, 06 2016. [37] Prof. William Kahan. A critique of john l. gustafson’s the end of error — unum computation and his a radical approach to computation with real numbers. http://people.eecs.berkeley.edu/ ~wkahan/UnumSORN.pdf, 06 2016.

49 Département TIC, 27 juillet 2018

[38] Peter Hofstee Jianyu Chen, Zaid Al-Ars. A matrix-multiply unit for posits in reconfigurable logic using (open)capi. https://posithub.org/conga/2018/docs/2-Jianyu-Chen.pdf, 03 2018. [39] Vassil S. Dimitrov. Do we really know how to compute geometric progressions ? https://posithub. org/conga/2018/docs/3-Vassil-Dimitrov.pdf, 03 2018. [40] Gerd Bohlender. Verification of numerical results, using posits, valids, and quires. https: //posithub.org/conga/2018/docs/4-Gerd-Bohlender.pdf, 03 2018. [41] Chung ShinYee. Provably correct posit arithmetic. https://posithub.org/conga/2018/docs/ 5-Shin-Yee-Chung.pdf, 03 2018. [42] Álmos Szabó Zoltán Lehóczky. High-level .net software implementations of unum type i and posit with simultaneous fpga implementation using hastlayer. https://posithub.org/conga/2018/ docs/7-Zoltan-Lehoczky-and-Almos-Szabo.pdf, 03 2018. [43] Artur Podobas. Accelerating posit-based computations using fpgas and opencl. https://posithub. org/conga/2018/docs/8-Artur-Podobas.pdf, 03 2018. [44] Calligo Technologies. Posit numeric unit (pnu) : Implementation – posit <32,2>. https: //posithub.org/conga/2018/docs/9-Calligo-Technologies.pdf, 03 2018. [45] Mark Charlebois. Compiling linux with llvm. https://llvm.org/devmtg/2012-04-12/Slides/ Mark_Charlebois.pdf, 03 2012. [46] Inc UNIX Systems Laboratories. Tool interface standard (tis) portable formats specification version 1.1. Technical report, TIS Committee, 10 1993. [47] American National Standards Institute. Ieee standard for binary floating-point arithmetic. Technical Report IEEE Std 754-1985, IEEE Computer Society, 07 1985. [48] IEEE Computer Society. Ieee standard for binary floating-point arithmetic. Technical Report IEEE Std 754-2008, IEEE Computer Society, 08 2008. [49] Enric Morancho. Unum : Adaptive floating-point arithmetic. Technical report, Departament d’Arquitectura de Computadors, Universitat Politècnica de Catalunya, 2016. [50] Sanjay L. Haridas Sushma S. Mahakalkar. Design of high performance ieee754 floating point multiplier using vedic mathematics. Technical report, GHRAET, Nagpur, India, 2014. [51] Laslo Hunhold. The unum number format : Mathematical foundations, implementation and comparison to ieee 754 floating-point numbers. Technical Report 1701.00722, Universität zu Köln, Mathematisches Institut, 11 2016. [52] Jian Zhang Christopher De Sa, Megan Leszczynski and Co. High-accuracy low-precision training. Technical report, Department of Computer Science, Cornell and Stanford Universities, 03 2018. [53] GNU Compiler Collection Project. 3.10 options that control optimization. https://gcc.gnu.org/ onlinedocs/gcc/Optimize-Options.html, 2018. [Online ; accessed 21-March-2018]. [54] GNU Compiler Collection Project. (internals) 4.3 routines for decimal floating point emulation. https://gcc.gnu.org/onlinedocs/gccint/Decimal-float-library-routines.html, 2018. [Online ; accessed 21-March-2018]. [55] GNU Compiler Collection Project. (internals) 4.3 routines for decimal floating point emulation. https://gcc.gnu.org/onlinedocs/gccint/Decimal-float-library-routines.html, 2018. [Online ; accessed 21-March-2018]. [56] GNU Compiler Collection Project. (internals) 6.3.9 anatomy of a target back end. https://gcc. gnu.org/onlinedocs/gccint/Back-End.html, 2018. [Online ; accessed 29-June-2018]. [57] GNU Compiler Collection Project. (internals) 8.1 option file format. https://gcc.gnu.org/ onlinedocs/gccint/Option-file-format.html, 2018. [Online ; accessed 21-March-2018]. [58] GNU Compiler Collection Project. (internals) 8.2 option properties. https://gcc.gnu.org/ onlinedocs/gccint/Option-properties.html, 2018. [Online ; accessed 21-March-2018].

50 Département TIC, 27 juillet 2018

[59] GNU Compiler Collection Project. (internals) 14.6 machine modes. https://gcc.gnu.org/ onlinedocs/gccint/Machine-Modes.html, 2018. [Online ; accessed 21-March-2018]. [60] GNU Compiler Collection Project. (internals) 17 machine descriptions. https://gcc.gnu.org/ onlinedocs/gccint/Machine-Desc.html, 2018. [Online ; accessed 21-March-2018]. [61] GNU Compiler Collection Project. (internals) 18.12 implicit calls to library routines. https://gcc. gnu.org/onlinedocs/gccint/Library-Calls.html, 2018. [Online ; accessed 21-March-2018]. [62] Wikipedia contributors. Floating-point arithmetic — wikipedia, the free encyclopedia. https://en. wikipedia.org/w/index.php?title=Floating-point_arithmetic&oldid=826333139, 2018. [Online ; accessed 2-March-2018]. [63] Wikipedia contributors. Floating point error mitigation — wikipedia, the free encyclopedia. https://en.wikipedia.org/w/index.php?title=Floating_point_error_mitigation& oldid=826334343, 2018. [Online ; accessed 2-March-2018]. [64] Wikipedia contributors. Unum (number format) — wikipedia, the free encyclopedia. https: //en.wikipedia.org/w/index.php?title=Unum_(number_format)&oldid=848011253, 2018. [Online ; accessed 05-July-2018].

51 Chapitre 9 Authentification

Par la présente, je soussigné, Julien Baeriswyl, déclare avoir réalisé seul ce travail et ne pas avoir utilisé d’autres sources que celles citées dans la bibliographie.

Date : Lieu :

Signature :

52 Annexes

53 Chapitre A Journal de travail

9.1 Révisions du document

Révision Date Auteur Description 0.1 2018-02-18 Baeriswyl Julien Création du document, brainstorming 0.2 2018-02-23 Baeriswyl Julien Bibliographie de base, introduction 0.2.1 2018-03-02 Baeriswyl Julien Liste des implémentations existantes 0.2.2 2018-03-05 Baeriswyl Julien Analyse rapide des implémentations 0.2.3 2018-03-08 Baeriswyl Julien Version Unum dans les documents 0.2.4 2018-03-09 Baeriswyl Julien Refactor resources 0.3 2018-03-12 Baeriswyl Julien Évaluation des contributions possibles 0.3.1 2018-03-20 Baeriswyl Julien Recherche sur les des soft-float 0.3.2 2018-03-21 Baeriswyl Julien 1st draft de la proposition de projet 0.3.3 2018-05-03 Baeriswyl Julien Tentative Markdown à reStructuredText 0.4 2018-05-04 Baeriswyl Julien Traduction de l’anglais au français 0.5 2018-06-06 Baeriswyl Julien Restructuration du document 0.5.1 2018-06-06 Baeriswyl Julien Ajout des notions mathématiques 0.5.2 2018-06-07 Baeriswyl Julien Explications sur le soft-float 0.5.3 2018-06-14 Baeriswyl Julien Correction des imprécisions 0.5.4 2018-06-14 Baeriswyl Julien Ajouts des références 0.5.5 2018-06-15 Baeriswyl Julien Mise à jour du journal 0.5.6 2018-06-15 Baeriswyl Julien Relecture, mise au propre 0.5.7 2018-06-15 Baeriswyl Julien Finalement, usage de LATEX

9.2 Planification initiale

Période Objectif Description S1-S3 Étude Recherches sur Unum et le soft-float S4 Étude Analyse des implémentations existantes S5 Étude Analyse du fonctionnement du soft-float S6 API Prototype bas-niveau en C de bibliothèque for Unum S7-S8 Intégration Correspondance au plus proche avec l’interface de GCC S9-S10 Validation Tests du fonctionnement des algorithmes (stabilité, cas limites) S11-S12 Performance Optimization des routines (grâce au debug et benchmarking) S13-S16 Comparaison Production de résultats comparable avec IEEE standard S17-S22 Hardware Bibliothèque générique (probablement en VHDL) pour FPGA

9.2.1 Suivi du planning Une baisse de productivité est survenue en semaine 5 à 7, notamment à cause de situation personnelle et de prise en main plus conséquente de certains outils associés au cours. Bien qu’une évaluation précise des heures n’ait pas été faite, le retard sur le temps de travail a presque été entièrement rattrapé.

En revanche, l’avancement du projet n’est pas aussi avancé que prévu, notamment pour les raisons suivantes : — La fatigue accumulée, qui réduit grandement mes facultés d’analyse, ce qui me pousse à tirer des conclusions parfois hâtives. — Au départ, une méconnaissance presque totale de la structure interne des logiciels à utiliser ou modifier, ce qui rend le dépannage plus délicat et hasardeux.

54 Département TIC, 27 juillet 2018

9.3 État actuel d’avancement

Une implémentation d’Unum pour GCC est en développement en prenant pour base certains principes algorithmiques des implémentations existantes. L’implémentation n’est pas mais pas encore validée. Ce retard est notamment dû à des difficultés à l’intégration, car l’analyse de la configuration interne lors de la compilation de GCC est encore incomplète. Ceci explique pourquoi je ne me suis pas immédiatement rendu compte que d’autres fichiers étaient utilisés à la place de l’implémentation générique.

L’analyse suit son cours afin de pouvoir mieux détailler et contrôler la compilation de GCC.

9.3.1 Processus d’intégration à GCC 6.4.0 Afin de mieux comprendre les mécanismes internes de GCC pour le soft-float, certaines étapes ont été effectuée : 1. Lire la documentation officielle de GCC sur le soft-float et la configuration. 2. Compiler une application simple de benchmarking avec/sans le support soft-float. 3. Exécuter le benchmark, ce qui a permis de voir la différence de performance. 4. Analyser les fichiers exécutables afin de voir la structure au niveau assembleur et comprendre comment le support est intégrés aux application (embarqué, chargement dynamique, etc). 5. Repérer les routines dans les sources de GCC. 6. Analyser la construction des routines. 7. Reproduire une interface similaire, mais pour les Posit. C’est lors de la phase 5 que mon erreur s’est produite. Lors de cette étape, j’ai identifié l’implémentation générique, mais pas les implémentations spécifiques. La raison principale est le nombre d’indirections (notamment des macros) qui réduisent la lisibilité des sources.

Par exemple, la routine __adddf3, c’est à dire l’addition pour les nombres binary64, possède une définition dans libgcc/soft-fp/adddf3.c. Cependant, dans libgcc/config/arm/sfp-machines.h, le nom __adddf3 est une macro qui est remplacée par __aeabi_dadd. Le nom __adddf3 n’est déclaré nulle-part ailleurs.

En outre, une fonction assembleur déclarée comme adddf3 dans libgcc/config/arm/ieee754-df.S existe et est celle utilisée dans les exécutables générés par GCC, mais son nom ne correspond pas à __adddf3, qui est le nom utilisé dans les symboles de l’exécutable.

Extrait de la routine dans un exécutable (format ELF):

000126a4 <__adddf3>: 126a4: e92d4030 push {r4, r5, lr} 126a8: e1a04081 lsl r4, r1, #1 126ac: e1a05083 lsl r5, r3, #1 126b0: e1340005 teq r4, r5 126b4: 01300002 teqeq r0, r2 126b8: 1194c000 orrsne ip, r4, r0 126bc: 1195c002 orrsne ip, r5, r2 ... 12944: 01310003 teqeq r1, r3 12948: 13811702 orrne r1, r1, #524288 ; 0x80000 1294c: e8bd8030 pop {r4, r5, pc}

55 Département TIC, 27 juillet 2018

Extrait du fichier Extrait du fichier libgcc/config/arm/ieee754-df.S : libgcc/softfp/adddf3.c : ARM_FUNC_START adddf3 DFtype ARM_FUNC_ALIAS aeabi_dadd adddf3 __adddf3 (DFtype a, DFtype b) { 1: do_push {r4, r5, lr} @ sp- = 12 FP_DECL_EX; .cfi_adjust_cfa_offset 12 @ CFA is now sp + previousOffset + 12 FP_DECL_D (A); .cfi_rel_offset r4,0 @ Registers are saved from sp to sp +8 FP_DECL_D (B); .cfi_rel_offset r5,4 FP_DECL_D (R); .cfi_rel_offset lr,8 DFtype r; @ Look for zeroes, equal values, INF, or NAN. FP_INIT_ROUNDMODE; shift1 lsl, r4, xh, #1 FP_UNPACK_SEMIRAW_D (A, a); shift1 lsl, r5, yh, #1 FP_UNPACK_SEMIRAW_D (B, b); teq r4, r5 FP_ADD_D (R, A, B); do_it eq FP_PACK_SEMIRAW_D (r, R); teqeq xl, yl FP_HANDLE_EXCEPTIONS; do_it ne, ttt COND(orr,s,ne) ip, r4, xl return r; COND(orr,s,ne) ip, r5, yl }

9.4 Planification à mi-travail

Période Description S17 Finir l’intégration avec GCC, validation avec les arrondis S18 Benchmarking et optimisations S19 Première implémentation hardware en VHDL pour FPGA S20 Validation par banc de tests (voire vérification formelle) S21 Benchmarking et optimisation du hardware S22 Analyse des résultats, finalisation du rapport

À noter que cette planification n’est pas encore validée, car il est possible qu’une réorientation soit faite. En effet, lors de la Conference for Next Generation Arithmetic, un intervenant nommé Artur Podobas a présenté une accélération des Posit sur FPGA [43].

Si son travail est probant et ouvert publiquement, alors la raison d’être d’une implémentation matérielle dans ce travail de bachelor deviendrait obsolète.

Auquel cas, ce travail de bachelor s’axerait alors sur le logiciel, avec par exemple un support totalement transparent au niveau du compilateur, ou encore l’ajout d’autres formats alternatifs parmi ceux présentés précédemment.

56