Pour comprendre comment fonctionne un ordinateur, il faut avant tout comprendre son mode de fonctionnement interne.
Les circuits électroniques sont capables de réaliser des calculs complexes en utilisant une représentation de l'information binaire.
Nous nous focaliserons plus particulièrement, au cours de ce chapitre, sur le microprocesseur vu en tant qu'élément d'un dispositif permettant d'exécuter les programmes. Notre but étant d'apprendre à programmer en assembleur, le langage exécuté par les microprocesseurs.
L'invention du transistor date du 23 Décembre 1947, lorsque William Shockley, Walter Brattain et John Bardeen mirent au point le transistor avec point de contact (point-contact transistor) aux Bell Laboratories.
Leur invention fut révélée au public en 1948 et ils obtinrent le prix Nobel en 1958.
The point contact transistor (size 1.25 inch)
From State of the Art, A Photographic History of the Integrated Circuit
Stan Augarten, Ticknor and Fields, 1983.
"L'une des plus importantes découverte du 20ème siècle, le transistor, fut une conséquence de la recherche sur les radars effectuée aux USA et en Grande Bretagne durant la seconde guerre mondiale. Alors qu'ils travaillaient sur une nouvelle méthode de détection d'objets volants, les scientifiques ont commencé à étudier une gamme de solides peu connus appelés semiconducteurs. Des matériaux comme le Silicium et le germanium, qui occupent la même colonne dans la table périodique des éléments, semblaient disposer d'un grand potentiel en tant qu'amplificateurs de courant et apparaissaient comme des substituts intéressants des tubes à vides."
(voir [Augarten 83], page 2)
Le but du projet initié aux Bell Labs en 1945 était de trouver une alternative au tubes à vides qui souffraient de plusieurs défauts :
L'ampoule électrique fut inventée par Henry Woodward en 1874. Son invention fut ensuite améliorée par Thomas Edison, puis John Ambrose Fleming qui créa la diode en 1904. Enfin Lee De Forest eut l'idée en 1906 d'ajouter troisème electrode à la diode et créa le tube à vide qu'il baptisa audion, mais fut plus connu sous l'appelation triode.
Quelques dates :
De nos jours la grande majorité des transistors des circuits intégrés sont de type MOSFET. Le Metal Oxide Semiconductor Field Effect Transistor - MOSFET) est dérivé du transistor à effet de champs (Field Effect Transistor - FET).
Transistor MOSFET (image issue de all about circuits)
La finesse de gravure (logic process) joue un rôle majeur dans l'amélioration des performances des transistors et donc des circuits intégrés. Son évolution est définie par l'ITRS (International Technology Roadmap for Semiconductors)
Si on est capable de graver plus finement un circuit, celui-ci occupera moins de place sur un morceau de Silicium : si on divise par 2 la taille du tracé, on divise par 4 la surface occupée par le circuit.
Pour un wafer de diamètre [d, mm] et un circuit de taille [S, mm2], le nombre de circuits que l'on peut placer sur le wafer est de de l'ordre de (Die Per Wafer [DPW]) :
Le prix d'un wafer varie entre \$200 et \$10000 en fonction de matériau (Silicon, Gallium Arsenide, Germanium), le dopage (Phosphore, Bore), la résistivité, l'épaisseur...
Procédé | Lithographie | Longueur porte | Wafer (mm) | Année |
Px60 | 130 nm | 70 nm | 200/300 | 2001 |
P1262 | 90 nm | 50 nm | 300 | 2003 |
P1264 | 65 nm | 35 nm | 300 | 2005 |
P1266 | 45 nm | 25 nm | 300 | 2007 |
P1268 | 32 nm | 18 nm | 300 | 2009 |
P1270 | 22 nm | ? | ? | 2011 |
P1272 | 14 nm | ? | ? | 2013 |
P1274 | 10 nm | ? | ? | 2015 |
Par exemple, avec une gravure en 32nm des circuits SRAM (mémoire cache), 291 Mbits sont formés par 1,9 Milliards de transistors (soit 6,22 T/bit).
Processeur | Transistors | Année |
4004 | 2.300 | 1971 |
8008 | 3.500 | 1972 |
8080 | 4.500 | 1974 |
8086 | 29.000 | 1978 |
80286 | 134.000 | 1982 |
80386 | 275.000 | 1985 |
80486 | 1.200.000 | 1989 |
Pentium | 3.100.000 | 1993 |
Pentium Pro | 5.500.000 | 1995 |
Pentium II | 7.500.000 | 1997 |
Pentium III | 9.500.000 | 1999 |
Pentium 4 | 42.000.000 | 2000 |
Itanium | 25.000.000 | 2001 |
Itanium 2 | 220.000.000 | 2002 |
Pentium D | 376.000.000 | 2006 |
Core 2 Duo (Conroe, 65 nm) | 291.000.000 | 2006 |
Core 2 Duo (Penryn, 45 nm) | 410.000.000 | 2007 |
Core 2 Quad (Penryn, 45 nm) | 820.000.000 | 2007 |
Processeur | Millions T. | Taille (mm2) |
Xeon 5300 (65nm) | 582 | 143 |
Core 2 Quad (Penryn, 45nm, 2007) | 820 | 107 |
Core i7 960 (4C,8T) (45nm, 2009) | 731 | 263 |
Core i7 980X (Gulftown, 6C,12T) (32nm, 2010, 12 Mo L3) | 1170 | 240 |
Intel Dunnington (45 nm, 6C) | 1900 | 503 |
Intel Nehalem-EX (45 nm, 8C) | 2300 | 984 |
Intel Westmere-EX (32 nm, 10C) | 2600 | 513 |
Pour plus d'informations : Anandtech.
voir l'article de Tomshardware : Comparativement au 10 nm, la nouvelle finesse de gravure permettrait de concevoir des puces 40 % plus performantes ou consommant 75 % d’énergie en moins. Pour arriver à leurs fins, les chercheurs ont utilisé des transistors avec grilles circulaires (GAAFinFET ou Gate All Around FinFET) apposés sur des nanofilms permettant de mieux contrôler les performances des circuits. Ces wafers en 5 nm ont été gravés avec des lasers à ultra violet extrêmes (EUV).
voir l'article de Tomshardware : Nouveau semi-conducteur offrant les mêmes performances que le silicium, mais avec une conductivité thermique beaucoup plus élevée.
On April 19, 1965 Electronics Magazine published a paper by Gordon Moore in which he made a prediction about the semiconductor industry that has become the stuff of legend. Known as Moore's Law, his prediction has enabled widespread proliferation of technology worldwide, and today has become shorthand for rapid technological change. (Intel)
Image issue du site canardpc
Voici un petit comparatif de rentabilité entre Core 2 et Core i7 :
Quel est le coût de revient dans chacun des deux cas pour produire 10_000 processeurs ?
Voir l'article suivant : Intel reveals Ice Lake Core architecture 10nm+
Depuis quelques années Intel s'organise pour faire évoluer ses processeurs suivant le modèle Tick/Tock (2007) :
Architecture | Finesse | Tick ou Tock | Année |
Conroe/Merom | 65nm | Tock | 2006 |
Penryn | 45nm | Tick | 2007 |
Nehalem | 45nm | Tock | 2008 |
Westmere | 32nm | Tick | 2010 |
Sandy Bridge | 32nm | Tock | 2011 |
Ivy Bridge | 22nm | Tick | 2012 |
Haswell | 22nm | Tock | 2013 |
Broadwell | 14nm | Tick | 2014 |
Skylake | 14nm | Tock | 2015 |
Kaby Lake | 14nm+ | Tock | 2016 |
Coffee Lake | 14nm++ | 2017 | |
Cannon Lake | 10nm | 2018? | |
Ice Lake | 10nm+ | 2018? | |
Tiger Lake? | 10nm++? | 2019? |
En 2016, Intel a modifié le modèle de développement Tick Tock en PAO :
En 2007, le marché des semi-conducteurs est estimé à 271 milliards de dollars.
rang 2006 | rang 2007 | société | % du marché mondial |
1 | 1 | Intel | 12,5 |
2 | 2 | Samsung Electronics | 7,4 |
4 | 3 | Toshiba | 4,6 |
3 | 4 | Texas Instruments | 4,5 |
8 | 11 | Advanced Micro Devices | 2,1 |
algèbre de Boole
circuits numériques
L'invention du microprocesseur date de 1971, lorsque la société Intel réalisa le 4004.
Depuis l'apparition du Intel 4004, l'architecture n'a eu de cesse d'évoluer et nous vivons une course constante à la performance que se livrent les deux géants que sont Intel et son concurrent AMD.
La recherche de performance, si elle ne semble pas nécessaire pour les machines destinées aux particuliers, est en revanche primordiale pour l'industrie ou les domaines de recherche à la pointe du progrès, comme par exemple :
Ainsi que nous l'avons vu (cf chapitre 2), l'architecture des microprocesseurs grand public repose sur l'architecture dite de Von Neumann pour laquelle l'unité de traitement des instructions et des données (le microprocesseur pour nous) se décompose en deux sous unités :
Afin de stocker temporairement les opérandes et les résultats des calculs, un microprocesseur est doté de registres qui sont des cellules mémoires.
Un registre est un espace mémoire situé à l'intérieur du microprocesseur chargé de stocker des données temporaires qui peuvent être :
Par exemple, sur l'Intel 8086, on trouve des registres d'une taille de 16 bits :
deux paramètres principaux permettent de caractériser un microprocesseur :
Viennent ensuite d'autres paramètres qui sont spécifiques aux différentes architectures, comme par exemple :
Ces 2 facteurs principaux (architecture, fréquence) conditionnent les performances de la machine qui sont mesurées :
Remarque : deux processeurs ayant la même fréquence de fonctionnement ne possèdent pas forcément les mêmes performances (cf suite du cours).
Voir le site www.spec.org
Le microprocesseur ou Central Processing Unit - CPU en anglais, n'est en fait capable de réaliser que 3 types d'instructions :
LOAD R,[mem]
STORE [mem],R
OPERATOR R3, R1, R2
Pour les microprocesseurs x86, on note :
OPERATOR R1, R2
ce qui correspond à
R1 <- R1 OPERATOR R2
On distingue deux classes d'architectures pour les micrprocesseurs :
ADD [EBX+ECX*4+8], EAX
réalise plusieurs opérations :
Architecture | Sigle | Description |
RISC | MIPS | Microprocessor without Interlocked Pipeline Stage |
RISC | ARM | Acorn Risc Machine (1987) ou Advanced Risc Machine |
RISC | POWER | Performance Optimization With Enhanced RISC 1-8 |
CISC | x86 | Intel, AMD |
CISC | 680x0 | Motorola |
La conception d'un microprocesseur pose de nombreux problèmes. Plus la structure du CPU est complexe, plus les procédures de test sont longues et plus il est difficile de déterminer d'éventuels défauts de conception. Un processeur RISC, de structure moins complexe qu'un processeur CISC, est donc plus simple à mettre en oeuvre.
Plusieurs facteurs ont encouragé par le passé la conception de machines à jeu d'instruction complexe (CISC) :
En effet, dans les années 70 les ordinateurs utilisaient de la mémoire magnétique (réalisée à partir de tores) pour stocker les programmes. Ce type de mémoire était cher et lent. Un premier changement s'opéra avec l'arrivée des DRAM mais restait l'épineux problème du prix des DRAM :
Le prix prohibitif des mémoires RAM et la lenteur des disques faisait qu'un code de programme était considéré comme intéressant s'il était compact.
Le processus de compilation des langages de haut niveau comme Pascal et C était lent et le code assembleur obtenu n'était pas toujours optimisé : mieux valait coder à la main.
Certains proposèrent de combler le fossé sémantique entre langage de haut niveau et assembleur afin de faciliter la tâche des programmeurs : en d'autres termes ils proposaient de faire en sorte que les instructions assembleur ressemblent aux instructions des langages de haut niveau.
On a toujours considéré que le code provenant d'un compilateur serait toujours moins performant que le code écrit à la main en assembleur par un programmeur. Cependant de nombreux progrès ont été réalisés depuis 1970.
Soit l'exemple suivant :
void swap(int t[], int k) {
int temp = t[k];
t[k] = t[k+1];
t[k+1] = temp;
}
void sort(int n, int t[]) {
int i, j;
for (i=0; i < n; i++)
for (j=i-1; j >= 0; --j)
if (t[j] > t[j+1]) swap(t,j);
}
Ce morceau de code a été traduit en assembleur par un programmeur et par un compilateur C. Le code produit par le compilateur C a obtenu un meilleur résultat à l'exécution :
programmeur : | 37,9s |
Compilateur C : | 25,3s |
Au milieu des années 70, deux facteurs sont venus ébranler les idées ancrées dans les esprits par les décennies précédentes :
Les résultats précédents peuvent se résumer par la phrase suivante : 80% des traitements des langages de haut niveau font appel à 20% des instructions du CPU. D'où l'idée d'améliorer la vitesse de traitement des instructions les plus souvent utilisées.
Des études réalisées en 1974 par John Cocke d'IBM (NY) et David Patterson 1975 montrèrent que seules 20 % des instructions d'un processeur réalisent 80 % des traitements d'un programme.
Durant les années 1980, les processeurs RISC-I et RISC-II de l'université de Berkeley virent le jour. Au début des années 1990, Apple, IBM et Motorola s'allièrent pour contrer Intel et sa prédominence sur le marché. De leur union naquit le PowerPC. On peut en outre évoquer la société MIPS qui a produit depuis 1984 des processeurs à architecture RISC ainsi que Sun Microsystems avec son SPARC (Scalable Processor ARChitecture).
Le concept RISC consiste à créer un jeu d'instructions simples mais très rapides. L'accès à la mémoire est simplifié grâce à l'utilisation de deux instructions (LOAD et STORE).
On peut ainsi :
Par opposition au RISC, l'architecture CISC désigne des microprocesseurs disposant d'un jeu d'instructions autorisant différents types d'accès aux données. Le but est ici de "coller" au plus près à la syntaxe des langages de programmation de haut niveau en fournissant des instructions proches de celles de ces langages.
Par exemple la grande majorité des instructions permet de faire référence à la mémoire.
Chaque architecture possède des avantages et des inconvénients :
En fait les processeur CISC se sont orientées progressivement vers une architecture avec un coeur d'exécution RISC, les instructions CISC sont traduites en micro-opérations RISC traitées par le coeur du processeur.
Voici un simple exemple de copie d'une tableau source vers un tableau destination qui permet d'appréhender les différences entre CISC / RISC.
on dispose de 32 registres.
a) Traduction non optimisée
b) Amélioration avec rep movsd
c) Amélioration avec passage des arguments dans les registres (fast call)
Le langage machine est le langage compris par le microprocesseur. Il existe différents langages machines qui dépendent du type de microprocesseur. Ce langage est difficile à maitriser puisque chaque instruction est codée par une séquence propre de bits. Afin de faciliter la tâche du programmeur, on a créé le langage assembleur qui utilise des mnémoniques pour le codage des instructions :
Langage machine |
Langage assembleur |
EZ-language |
a1 18 a0 04 08
|
MOV AX,[0x804a018]
|
a,b,c are integer
|
Dans cette section, nous allons donner un aperçu du langage assembleur des microprocesseurs Intel de la famille 80x86 afin de pouvoir utiliser ce langage par la suite.
Le Pentium, qui est dérivé du 80486, est un microprocesseur CISC capable d'exécuter un programme dans différents modes de fonctionnement :
Il existe 8 registres généraux (General Purpose Registers) :
Parmi ces registres on distingue :
Registres du Pentium 4 avec architecture 64 bits
(image issue du site de Pierre Marchand, Université de Laval, Canada)
Le calcul d'une adresse mémoire physique dépend du mode de fonctionnement du processeur.
Pour solutionner ce problème on utilise une technique appelée ségmentation qui consiste à combiner deux registres de 16 bits pour obtenir une adresse sur 20 bits suivant la formule :
adresse 20 bits = registre segment × 16 + offset
L'offset peut être une valeur numérique, un registre ou une combinaison des deux. Toutes les combinaisons entre registre segment et registre index ne sont pas possibles :
Registre Segment |
Registre Pointeur |
Spécification |
CS | IP | Compteur ordinal |
SS | SP | Sommet de pile |
SS | BP | Accès à la pile |
DS | SI | Source pour LODSB/W |
ES | DI | Destination pour STOSB/W |
DS | BX |
Pour être plus exact, la description de l'offset en mode protégé est donnée par :
Offset = Base + Index × Echelle + deplacement
avec :
typedef struct {
char *name;
int age;
} Person;
Person tab[10];
tab[3].age = 10;
sera traduit par en mode 32 bits en :
mov ebx, 0x.... ; adresse du tableau 'tab'
mov ecx, 3
mov [ebx + ecx * 8 + 4], 10
Dénomination | Qté en bits | Codage Assembleur |
bit | 1 | DBIT |
byte (octet) | 8 | DB |
word (mot) | 16 | DW |
double word | 32 | DD |
quad word | 64 | DQ |
Le Pentium est capable de traiter des quantités allant jusqu'à 64 bits, soit deux doubles mots de 32 bits, voire jusqu'à 80 bits pour les réels (au niveau du coprocesseur).
La taille des instructions varie de 1 à plusieurs octets, par exemple :
Taille (en bits) | 8 | 16/32 |
Instruction | CALL | adresse |
Taille (en bits) | 5 | 3 |
Instruction | PUSH | Reg |
Il existe conventionnellement dans les programmes élémentaires écrits en assembleur entre 2 à 3 segments :
Un programme assembleur aura donc la structure suivante (cas MASM/TASM) :
STACK SEGMENT 4096 ; Pile de 4096 octets
DATA SEGMENT PUBLIC
var0 DB ?
var1 DW 1234
var2 DD ?
...
DATA ENDS
CODE SEGMENT PUBLIC
ASSUME DS:DATA, CS:CODE
MOV AX,var0
...
CODE ENDS
Pour un programme écrit en NASM, la syntaxe diffère :
; GLOBAL indique que main est un sous-programme visible des autres fichiers objets
global main
; EXTERN indique que les sous-programmes existent dans d'autres fichiers objets
extern printf
extern scanf
; ========================
; ===== DATA SECTION =====
; ========================
section .data
msg_1: db 'la somme des éléments du tableau est %d',10,0
msg_2: db 't[%d]=%d',10,0
taille EQU 20
tableau: times taille dd 0
; COMMON indique l'existence d'une donnée dans un autre fichier objet
; qui occupe 4 octets
common n 4
; ========================
; ===== CODE SECTION =====
; ========================
section .text
main:
push ebp
mov ebp,esp
...
Dans la suite de cette section nous décrivons les instructions de bases pour écrire des programmes simples en assembleur.
De manière synthétique, les différents formats de MOV sont les suivants, cf page 640 du Intel Instruction Set Reference (A-M), ou mov.pdf.
Les instructions de transfert permettent l'affectation de valeurs entre registres et mémoire.
Exemples :
Les instructions arithmétiques sont les suivantes :
On notera que MUL accepte 1 opérande de type r/m(8/16/32/64), alors que IMUL en accepte 1, 2 ou 3 (cf Intel Instruction Set Reference (A-M))
Exemples :
Exemples :
Instruction | Signification | Signé (S) ou non (U) |
ja | Jump if above | U |
jae | Jump if above or Equal | U |
jb | Jump if below | U |
jbe | Jump if below or Equal | U |
jc | Jump if Carry | |
jcxz | Jump if CX is Zero | |
je | Jump if Equal | |
jecxz | Jump if ECX is Zero | |
jz | Jump if Zero | |
jg | Jump if greater | S |
jge | Jump if greater or Equal | S |
jl | Jump if less | S |
jle | Jump if less or Equal | S |
jmp | Unconditional jump | |
jna | Jump Not above | U |
jnae | Jump Not above or Equal | U |
jnc | Jump if Not Carry | |
jncxz | Jump if CX Not Zero | |
jne | Jump if Not Equal | |
jng | Jump if Not greater | S |
jnge | Jump if Not greater or Equal | S |
jnl | Jump if Not less | S |
jnle | Jump if Not less or Equal | S |
jno | Jump if Not Overflow | |
jnp | Jump if Not Parity | |
jns | Jump if Not signed | |
jnz | Jump if Not Zero | |
jo | Jump if Overflow | |
jp | Jump if Parity | |
jpe | Jump if Parity Even | |
jpo | Jump if Parity Odd | |
js | Jump if signed | |
jz | Jump if Zero |
documentation de nasm : documentation
On peut créer des macro-commandes qui permettent de rendre l'écriture d'un programme moins pénible :
on utilise gcc -S -masm=intel a.c afin d'obtenir un fichier a.s qui contient le code assembleur.
Désassembler un programme consiste à obtenir son code source assembleur à partir de son exécutable.
Pour désassembler un programme sous Linux il faut utiliser la commande objdump :
objdump -d -M intel -r -S -l --no-show-raw-insn -j .text <monexe>
Pour vous simplifier la vie, créer un alias dans votre fichier ~/.bashrc :
alias myobjdump='objdump -d -M intel -r -S -l --no-show-raw-insn -j .text'
En 32 bits, le passage de paramètres à des sous-programmes (procédures ou fonctions) est effectué de manière générale au travers de la pile. Les variables locales sont également allouées dans la pile. Lors de l'appel d'un sous-programme on réalise les opérations suivantes :
La pile possède une taille maximale : 4, 8 ou 16 ko en général. Au début le pointeur de pile ESP prend la taille maximale de la pile. Lorsque l'on empile une valeur on décrémente ESP. Les instructions PUSH et POP ont donc le comportement suivant :
Lors du retour de sous-programme les paramètres sont toujours présents dans la pile, il faut donc les supprimer. Il existe ici deux manières de procéder :
Enfin, lors de l'appel de fonctions, on peut utiliser la pile pour passer la valeur de retour de la fonction ou un registre comme c'est le cas dans l'exemple précédent.
// sous-programme appelé
int sum( int a, int b ) {
int r;
r = a + b;
return r;
}
// sous-programme appelant
int main( ) {
sum(1,2);
return 0;
}
A l'intérieur d'un sous-programme on utilise généralement la pile afin d'allouer les variables locales. Afin de faciliter l'accès aux paramètres et aux variables locales on utilise le registre EBP.
Adresse | Code | Instructions (main) |
08048A20 | 68 02 00 00 00 | PUSH DWORD 2 |
08048A25 | B8 01 00 00 00 | MOV EAX,1 |
08048A2A | 50 | PUSH EAX |
08048A2B | E8 23 00 00 00 | CALL 08048A53 |
08048A30 | ... | ... |
Adresse | Code | Instructions (sum) |
08048A53 | 55 | PUSH EBP |
08048A54 | 89 E5 | MOV EBP,ESP |
08048A56 | 81 EC 04 00 00 00 | SUB ESP,4 ; (variable r, équivalent à PUSH EAX) |
08048A5C | 8B 45 08 | MOV EAX,[EBP+8] |
08048A5F | 03 45 0C | ADD EAX,[EBP+12] |
08048A62 | 89 45 FC | MOV DWORD [EBP-4],EAX |
08048A65 | 8B 45 FC | MOV EAX,DWORD [EBP-4] |
08048A68 | 89 EC | MOV ESP,EBP |
08048A6A | 5D | POP EBP |
08048A6B | C3 | RET |
Voici l'état de la pile une fois à l'intérieur de la fonction sum :
ESP | Valeur (hexa) | EBP | Indication |
ESP-4 | 00.00.00.02 | EBP+12 | second paramètre |
ESP-8 | 00.00.00.01 | EBP+8 | premier paramètre |
ESP-12 | 08.04.8A.30 | EBP+4 | adresse de retour du sous-programme |
ESP-16 | ??.??.??.?? | EBP+0 | ancienne valeur de EBP |
ESP-20 | ??.??.??.?? | EBP-4 | variable temporaire r |
Question : pourquoi le langage C utilise t-il une suppression des paramètres par l'appelant ?
Question : quelle est la taille de la pile sous Linux ?
ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 64159
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 64159
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
En outre, en mode 32 bits, on s'attend à ce que les registres EBP, EBX, EDI et ESI ne soient pas modifiés lors de l'appel d'un sous-programme. Cela implique que le sous-programme devra sauvegarder les valeurs de ces registres temporairement dans la pile, puis les restaurer avant de quitter le sous-programme.
Exemples d'appels pour la fonction int get(int *t, size_t i) { return t[i]; } :
push ebp
mov ebp, esp
mov eax, DWORD PTR [ebp+12] ; eax = i
lea edx, [0+eax*4] ; edx = eax * 4
mov eax, DWORD PTR [ebp+8] ; eax = t
add eax, edx ; eax = &t[i]
mov eax, DWORD PTR [eax] ; eax = t[i]
mov esp, ebp
pop ebp
ret
mov edx, DWORD PTR [esp+8] ; edx = i
mov eax, DWORD PTR [esp+4] ; eax = t
mov eax, DWORD PTR [eax+edx*4] ; eax = t[i]
ret
mov eax, DWORD PTR [ecx+edx*4]
ret
push rbp
mov rbp, rsp
mov QWORD PTR [rbp-8], rdi ; sauve rdi
mov QWORD PTR [rbp-16], rsi ; sauve rsi
mov rax, QWORD PTR [rbp-16] ; eax = i
lea rdx, [0+rax*4] ; rdx = 4*rax = 4*i
mov rax, QWORD PTR [rbp-8] ; rax = t
add rax, rdx ; rax = &t[i]
mov eax, DWORD PTR [rax] ; eax = t[i]
pop rbp
ret
mov eax, DWORD PTR [rdi+rsi*4]
ret
voir ce document pour plus de précisions.
Le temps d'exécution d'un programme est donné par la formule suivante :
$$T_{exec} = N_{ins} × CPI × T_{cycle}$$
Les différentes évolutions des ordinateurs ont pour but de diminuer le temps d'exécution des programmes.
Il a donc fallu élaborer des solutions capables de diminuer le temps nécessaire au traitement des instructions qu'elles soient CISC ou RISC.
Les architectures des processeurs modernes jouent sur plusieurs plans, en tentant de maximiser :
Pour schématiser, on peut dire que le traitement d'une instruction passe par 5 étapes fondamentales :
FRONT END |
FETCH | Il s'agit de l'étape de chargement depuis la mémoire de la prochaine instruction à exécuter |
DECODE | L'instruction est ensuite décodée et traduite pour être interprétée | |
LOAD OPERAND | si l'instruction nécessite des données en provenance de la mémoire ou de registres, on envoie une requête afin de les récupérer | |
BACK END |
EXECUTE | L'instruction est ensuite exécutée par l'UAL s'il s'agit d'une opération arithmétique ou logique |
WRITE RESULT | Le résultat est mis à jour dans un registre ou en mémoire |
De manière schématique :
Lors de l'exécution d'une instruction, on attend d'avoir effectué les 5 étapes de traitement avant de passer au traitement de l'instruction suivante.
Le but du pipeline consiste à diminuer le temps d'attente entre le traitement de chaque instruction. Plutôt que de disposer d'une unité de traitement qui réalise les 5 étapes précédentes, on décompose l'unité de traitement en 5 sous-unités. Les 80486 sont les premiers microprocesseurs de la gamme Intel à utiliser le pipeline.
Dès que la première instruction a terminé l'étape FETCH, elle passe dans la sous-unité DECODE. Dans le même temps, l'instruction suivante passe dans l'étape FETCH.
Il est préférable que chaque étpape de traitement associée à un étage du pipeline s'exécute en un cycle d'horloge. Si ce n'est pas le cas, on décompose une étape en plusieurs sous-étapes et on allonge ainsi la longueur du pipeline.
Vue suivant l'utilisation des étages du pipeline :
Question : quel est le gain théorique d'un pipeline de $k$ étages ?
Comme on peut le voir sur le schéma précédent, le gain est intéressant puisque l'instruction 5 se termine au bout de 9 cycles d'horloge alors que dans un modèle d'exécution sans pipeline elle serait exécutée au bout de 25 cycles.
Le gain apporté par un pipeline de $k$ étages est donné par le calcul suivant :
Le gain est donné par le rapport $lim_{n → ∾} (n × k) / (k + n - 1)$ soit $k$.
Exemples de pipelines pour architectures P6 et Netburst
L'autre intéret du pipeline est qu'il permet l'amélioration des performances avec la montée en fréquence. On pourra lire à ce sujet l'excellent article de Franck Delattre et Marc Prieur sur Hardware.fr intitulé : Intel Core Duo 2
|
L'exécution de l'instruction I2 nécessite que l'instruction I1 ait été réalisée. Cela implique au niveau du pipeline des états d'attente (stall). |
Certains mécanismes permettent cependant de remédier à ce genre de problème (réordonnancement des instructions ou forward after execute).
Exemple 1 | Exemple 2 |
|
|
|
Les instructions de branchement obligent, quant à elles, à vider le pipeline.
|
Si le résultat de la comparaison de ECX avec la valeur 100 est vrai alors on doit déplacer le pointeur d'instruction (IP) vers end_while et vider le pipeline qui contient les instructions ADD EAX, ECX et INC ECX. |
Vider le pipeline prend beaucoup de temps d'autant plus que le pipeline possède un nombre important d'étages. Pour remédier à ce genre de problème on utilise un mécanisme appelé prédiction de banchement qui a pour but de recenser lors de branchements le comportement le plus probable.
Les mécanismes de prédiction de branchement permettent d'atteindre une fiabilité de prédiction de l'ordre de 90 à 95 %.
Une autre amélioration possible consiste à disposer de plusieurs unités d'exécutions. Si on dispose de n unités d'exécution, on divise théoriquement le temps d'exécution par n.
Cependant, disposer d'une batterie d'unités de traitement (ou d'exécution) n'est pas rentable si on ne peut occuper à plein régime chacunes de ces unités.
Il s'agit ici de trouver un compromis entre amélioration en longueur et amélioration en largeur. Deux modèles semblent se détacher :
Le coprocesseur est un circuit dédié au calcul des nombres flottants (réels). Du 8086 au 80486SX, les microprocesseurs Intel pouvaient utiliser un coprocesseur externe. A partir du 80486DX, le coprocesseur a été intégré au niveau du die.
on retrouve le même schéma pour les opérations de base :
Les instructions de comparaison changent les bits de statut du coprocesseur mais ceux-ci ne sont pas accessibles directement. Il faut transférer ces bits vers les bits du registre EFLAGS comme suit :
; if (x > y) ...
;
fld qword [x]
fcomp qword [y]
fstsw ax ; place les bits Z,C,F dans AX
sahf ; stocke AH dans EFLAGS
jna else ; pour comparaison de nombres non signés
then:
; code du then
jmp end_if
else:
; code du else
end_if:
A partir du Pentium Pro, de nouvelles instructions qui modifient directement le registre EFLAGS ont été ajoutées :
section .data
deux: dd 2.0
trois: dd 3.0
section .text
(1) FLD dword [deux]
(2) FLD dword [trois]
(3) FDIV st1
opération | st0 | st1 | st2 | ... | st7 |
(1) | 2 | 0 | 0 | ... | 0 |
(2) | 3 | 2 | 0 | ... | 0 |
(3) | 1.5 | 2 | 0 | ... | 0 |
section .text
(1) FLD dword [deux]
(2) FLD dword [trois]
(3) FDIV st1,st0
opération | st0 | st1 | st2 | ... | st7 |
(1) | 2 | 0 | 0 | ... | 0 |
(2) | 3 | 2 | 0 | ... | 0 |
(3) | 3 | 0.666 | 0 | ... | 0 |
section .text
(1) FLD dword [deux]
(2) FLD dword [trois]
(3) FDIVP st1,st0 ; fdivP
opération | st0 | st1 | st2 | ... | st7 |
(1) | 2 | 0 | 0 | ... | 0 |
(2) | 3 | 2 | 0 | ... | 3 |
(3) | 0.66 | 0 | 0 | ... | 3 |
section .text
(1) FLD dword [deux]
(2) FLD dword [trois]
(3) FDIV st0,st1
opération | st0 | st1 | st2 | ... | st7 |
(1) | 2 | 0 | 0 | ... | 0 |
(2) | 3 | 2 | 0 | ... | 3 |
(3) | 1.5 | 2 | 0 | ... | 0 |
Il existe un moyen automatique assez simple :
Note : dans le cas d'une constante on doit la stocker en mémoire et la charger avec FLD : FLD [mem] ou FLD STi
Par exemple, à partir de $$(x + y) / (√x × z - y)$$
on obtient l'expression postfixe :
x y + x sqrt z * y - /
que l'on traduit en :
FLD dword [x]
FLD dword [y]
FADDP ST1, ST0
FLD dword [x]
FSQRT
FLD dword [z]
FMULP ST1, ST0
FLD dword [y]
FSUBP ST1, ST0
FDIVP ST1, ST0
Autre exemple : Produit de deux float en assembleur sans coprocesseur : html (code source)
Sous Linux pour connaître les différentes technologies dont dispose un microprocesseur, il faut utiliser la commande suivante et regarder le champ flags :
\$ cat /proc/cpuinfo
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 158
model name : Intel(R) Core(TM) i5-7400 CPU @ 3.00GHz
stepping : 9
microcode : 0x42
cpu MHz : 1167.304
cache size : 6144 KB
physical id : 0
siblings : 4
core id : 0
cpu cores : 4
apicid : 0
initial apicid : 0
fpu : yes
fpu_exception : yes
cpuid level : 22
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36
clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc
art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni
pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1
sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm
3dnowprefetch intel_pt tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1
avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt xsaveopt xsavec xgetbv1 dtherm
ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp
....
Principe des processeurs vectoriels (Intel)
au lieu de faire:
float x[4], y[4], z[4];
for (int i=0; i<4; ++i) {
z[i] = x[i] + y[i]
}
on réalise une seule opération en parallèle sur un registre capable de contenir 4 floats
z[0:3] = x[0:3] + y[0:3]
Les processeurs vectoriels utilisent une architecture qualifiée de SIMD (Single Instruction Multiple Data) dans la classification de Flynn. Il sont capables d'effectuer la même opération sur plusieurs données différentes en même temps.
Les processeurs actuels intègrent des unités de calcul vectoriel dédiées au multimédia :
Les unités MMX comprennent, 8 registres de 64 bits (mm0 à mm7), ces registres permettent de manipuler les données sous forme :
Historique SSE Intel (Intel), tiré du site de Markus Püschel
Principe des processeurs vectoriels (Intel)
Les unités SSE comprennent, en mode 32 bits, 8 registres de 128 bits (xmm0 à xmm7), ces registres permettent de manipuler les données sous la forme :
Les instructions peuvent être classées en 3 catégories :
Exemples de quelques instructions :
La plupart des compilateurs C possèdent une bibliothèque <xmmintrin.h> qui permet d'utiliser des instructions liées aux unités SSE.
Par exemple sous Ubuntu en 32 bits, les fichiers .h se trouvent dans le répertoire /usr/lib/gcc/i686-linux-gnu/4.8/include/
typedef float __m128 __attribute__ ((__vector_size__ (16), __may_alias__));
typedef long long __m128i __attribute__ ((__vector_size__ (16), __may_alias__));
typedef double __m128d __attribute__ ((__vector_size__ (16), __may_alias__));
typedef float __m256 __attribute__ ((__vector_size__ (32),
__may_alias__));
typedef long long __m256i __attribute__ ((__vector_size__ (32),
__may_alias__));
typedef double __m256d __attribute__ ((__vector_size__ (32),
__may_alias__));
Liens concernant le SSE :
Advanced Vector Extensions (AVX) est une extension du SSE proposé par Intel en Mars 2008 et implantée à partir de 2011 (Q1) sur les processeurs Intel Sandy Bridge puis sur les AMD Bulldozer (Q3 2011).
AVX permet notamment
Advanced Vector Extensions 2 (AVX2) apparaît en Juin 2013 avec les Intel Haswell et étend le jeu d'instruction AVX.
Exemple : AVX2 des processeur Intel Haswell
vmovdqa ymm1, [edi + ecx] ; charge 8 entiers x[i:i+7]
vmovdqa ymm3, [esi + ecx] ; charge 8 entiers y[i:i+7]
vpxor ymm0, ymm0, ymm0 ; mise à 0 de ymm0
vpor ymm2, ymm1, ymm3 ; ymm2 = x[i:i+7] | y[i:i+7]
vpand ymm1, ymm1, ymm3
vpcmpeqd ymm0, ymm0, ymm1
vpmovmskb ebx, ymm0
and ebx, 0x11111111
vpblendvb ymm1, ymm1, ymm2, ymm0
vmovdqa [edx + ecx], ymm1
popcnt ebx, ebx
add eax, ebx
Les microprocesseurs actuels exécutent les instructions dans un mode dit "dans le désordre" (out of order).
Les instructions x86 (appelées macro-opérations) sont lues depuis le compteur ordinal (CS:EIP) dans un ordre précis. Elles sont ensuite décodées et traduites en une à plusieurs micro-opérations qui peuvent être exécutées dans un ordre différent de celui des instructions x86 auxquelles elles correspondent. Il faut ensuite faire en sorte de retirer (retirement ou result write back) les instructions dans l'ordre initial afin de garder la cohérence.
Ce genre de technique permet d'accélérer le traitement des instructions en tentant de minimiser les états d'attentes, mais pose également de nombreux problèmes à résoudre.
Les instructions sont chargées (FETCH) dans l'ordre puis décodées. Elles sont alors :
Le cheminement d'une instruction est donc le suivant :
Un autre point important concerne une technique appelée Register Renaming utilisée pour que le mécanisme précédent fonctionne. Les microprocesseurs x86 jusqu'au Pentium 4 disposent uniquement de 8 registres généraux. Pour que l'exécution des instructions du ROB soit possible, le Pentium dispose en interne de plusieurs registres qui sont des "copies" des registres généraux.
L'approche VLIW (pour Very Long Instruction Word, EPIC chez Intel) est une approche prometteuse mais qui n'a pas connu pour le moment le succès attendu. Elle a été mise en oeuvre au sein du processeur Itanium d'Intel.
Cette technique consiste a coder plusieurs instructions dans une seule grande instruction de manière à utiliser au mieux les unités d'exécution.
Par exemple pour l'Itanium, les instructions sont codées sur 128 bits :
Instruction 2 41 bits |
Instruction 1 41 bits |
Instruction 0 41 bits |
Gabarit 5 bits |
Intel a présenté, le 1er Novembre 2007, 7 nouveaux processeurs Itanium. Les modèles de la série 9100 se caractérisent par une architecture double coeur cadencés à 1,60 GHz (modèles N) et 1,66 GHz (série M). La taille du cache L3 varie de 8 Mo (9130M) à 24 Mo (9150N et M). La fréquence du FSB passe à 667 MHz pour la gamme M (9150, 9140 et 9130) contre 400/533 pour le reste de la série.
En mai 2017, Intel annonce que l'Itanium 9700 Kittson sera le dernier processeur utilisant le jeu d’instruction IA–64 (cf news tomshardware).
Depuis plusieurs années, les fabricants d'ordinateurs proposent des machines qui possèdent plusieurs processeurs : on qualifie ces machines de bi/quadri ou octo-processeurs suivant qu'elles connectent sur la même carte mère 2, 4 ou 8 processeurs. Il existera donc 2, 4 ou 8 sockets sur la même carte mère.
Le multi-coeur (multicore) consiste à ne disposer que d'un seul socket pour connecter un processeur composé de plusieurs coeurs de processeur. L'intérêt par rapport à la solution précédente réside dans le gain de performance. Les données n'ont pas en effet à transiter entre 2 processeurs en passant sur la carte mère.
Le coeur comprend les éléments suivants :
L'hyperthreading (où Simultaneous Multithreading = SMT) représente la première tentative chez Intel de simulation d'un processeur double coeur. Cette technologie a été mise en place sur le Pentium 4 fonctionnant à 3.06 Ghz HT sorti en Novembre 2002.
L'hyperthreading permet d'utiliser au mieux les ressources du processeur lorsqu'il est amené à gérer plusieurs threads simultanément. L'HT apporte un gain de performance minime mais une souplesse d'utilisation indéniable. Notamment lorsqu'un programme nécessite énormément de ressources, l'hyperthreading permet de garder la main sur le système.
Les premiers processeurs double coeur pour PC sont apparus en Avril 2005. Il s'agissait des Pentium D d'Intel et des Athlon 64 X2 d'AMD.
Processeur | Fréquence | Cache L2 | Prix |
Athlon 64 X2 4200 + | 2200 Mhz | 2 x 512 ko | $537 |
Athlon 64 X2 4800 + | 2400 Mhz | 2 x 1024 ko | $1001 |
Pentium D 820 | 2800 Mhz | 2 x 1024 ko | $241 |
Pentium EE 840 | 3200 Mhz | 2 x 1024 ko | $999 |
Les premiers Pentium 4 D (coeur Smithfield) n'ont pas été un succés. En fait Intel a voulu faire un effet d'annonce, en mettant le premier sur le marché, un processeur dual-core de manière à reléguer AMD au second plan. Cependant, le Pentium 4 D Smithfield est un processeur fait "à la va-vite". Il est composé de deux coeurs Prescott et chaque coeur dispose de sa propre interface de bus. Lorsque les coeurs communiquent ils doivent passer par le FSB. Ce système est donc équivalent en quelque sorte à un système bi-processeur.
Pentium 4 à coeur Smithfield
L'évolution du Smithfield est le Presler.
Coeur | Gravure | Surface | Transistors | Cache L2 | FSB |
Smithfield | 90 nm | 206 mm2 | 230 Millions | 2 x 1 Mo | 200 Mhz (x4) |
Presler | 65 nm | 376 mm2 | 376 Millions | 2 x 2 Mo | 266 Mhz (x4) |
Les processeurs AMD dual-core (X2) ont été pensés depuis plusieurs années. Leur conception est donc bien plus aboutie que celle des Pentium D d'Intel. Les premiers Athlon X2 ont été mis en service le 31 Mai 2005. Cependant, ils ne sont pas plus performants que les Intel Pentium D avec coeur Presler.
Schéma des Athlon 64 X2 d'AMD
Coeur | Gravure | Surface | Transistors | Cache L2 | FSB |
Manchester, Brisbane (AM2) | 90 nm | 199 mm2 | 233 Millions | 2 x 512 ko | 200 Mhz (x2) |
Toledo, Windsor (AM2) | 90 nm | ? mm2 | ? Millions | 2 x 512 ko | 200 Mhz (x2) |
Intel annonce lors de l'IDF de Septembre 2006 la venue prochaine du Quadro un processeur quad-core, muni de 4 coeurs donc.
Ce processeur le QX6700 (core Kentsfield) correspond à la mise en place de deux Core 2 Duo mis côte à côte. En gros, il ne s'agit pas d'un véritable quad core, mais Intel nous refait le coup du Pentium D (2 coeurs E6700 à 2,66 Ghz).
Le Kentsfield n'apporte aucun gain par rapport au E6700 sauf pour les applications multithreadées, capables de répartir la tâche totale sur les différents coeurs.
Source TT-Hardware (12 février 2007)
Intel a pour la première fois atteint le cap mytique du Teraflops en 1996 avec presque 10 000 processeurs Pentium Pro 200 MHz interconnectés. L'ASCI Red consommait ainsi plus de 500 kW et autant pour la climatisation des locaux soit 1000 kW... Une dizaine d'années plus tard, Intel atteint à nouveau 1 Teraflops mais avec un seul processeur à 3,16 GHz et avec une consommation de ridicule de 62 Watts !
Présenté lors de l'ISSCC (International Solid State Circuits Conference), le TeraScale se compose de 80 cores comprenant notamment 2 unités de calcul en virgule flottante et des ports de communication. Il ne s'agit pas ici de cores comparables à ceux des processeurs classiques que nous connaissons. Ils utilisent en outre une architecture spécifique VLIW (Very Long Instruction Word). La puce compte un total de 100 millions de transistors gravés en 65 nm et occupe 275 mm. A titre indicatif, un Core 2 Duo compte 290 millions de transistors répartis sur 143 mm². A 3,16 GHz, le TeraScale ne demande qu'une tension de 0,95 v et consomme 62 watts pour dégager une puissance de calcul de 1,01 Teraflops...
Selon Intel, ce type de puce composée de cores interconnectés par un réseau maillé en 2D permet des développements beaucoup plus rapides. La conception d'un processeur traditionnel comparable aurait demandé deux fois plus de temps. Justin Rattner, directeur technique d'Intel, estime que ce type de processeur pourrait arriver dans le commerce d'ici moins de cinq ans.
On peut penser que la nouvelle ligne directrice chez Intel est à la multiplication des cores simples. Un tendance qui se retrouve dans le projet de processeur graphique Intel prévu pour 2009.
AMD a annoncé le 29 Septembre 2006, qu'il allait produire un CPU quad core K8L en 65 nm : le Barcelona (ou Altair). Il disposera de 4 x 64 Ko de cache L1, de 4 x 512 Ko de cache L2 et de 2 Mo de cache L3 partagés.
10 septembre 2007: annonce de la sortie du K10 Barcelona (serveur) qui est une architecture 4 cores :
Novembre 2007 : les premiers tests effectués sur les AMD Phenom 9600 (2,3 Ghz) montrent que ceux-ci sont bien moins performants que les Quad Core Intel Q6600 sortis depuis plus d'un an (TomsHardware.com a noté qu'un Phenom 9600 était en moyenne 13,5% moins performant qu'un Intel Q6600). Etant donné que ces 2 processeurs coûtent dans les 220 €, il n'y a aucun intérêt à acheter un Phenom : coup dur pour AMD !
Décembre 2007 : on apprend que le Phenom souffrirait d'un bug lié au cache L3 qui a pour conséquence de geler le système. Un patch peut être appliqué au BIOS et permet d'éviter le bug, mais on note alors une baisse de 10% en moyenne des performances !!Il faudra attendre la révision B3 prévue pour le début 2008.
Décembre 2007 : on notera qu'Intel a également détecté un bug sur ses Quad Core (Yorkfield, 45nm). Il faudra attendre mars 2008 pour disposer de processeurs exempts de bugs.
Les deux premiers modèles du genre ont pour nom de code Toliman (T7600 et T7700), ils seront gravés en 65 nm, compatibles HyperTransport 3.0 et équipés d'un contrôleur de mémoire vive DDR2-800 intégré. Le tout viendra s'enficher sur un socket AM2+.
Au mois de Septembre 2008, Intel a inauguré la série des processeurs Xeon Dunnington X7400 à 6 coeurs. Ces processeurs sont composés de 3 die à double-coeurs. Le prix du processeur est de $2700 environ.
Processeur | Coeurs | Fréquence | Cache L3 | Consommation | Prix* |
X7460 | 6 | 2,66 GHz | 16 Mo | 130W | 2 729 |
L7455 | 6 | 2,13 GHz | 12 Mo | 65W | 2 729 |
E7450 | 6 | 2,40 GHz | 12 Mo | 90W | 2 301 |
L7445 | 4 | 2,13 GHz | 12 Mo | 50W | 1 980 |
E7440 | 4 | 2,40 GHz | 16 Mo | 90W | 1 980 |
E7430 | 4 | 2,13 GHz | 12 Mo | 90W | 1 391 |
E7420 | 4 | 2,13 GHz | 8 Mo | 90W | 1 177 |
En mars 2010, Intel introduit le Gulftown (Core i7 980X), version Desktop du Dunnington :
voir à ce sujet le site AnandTechcom.
Les premiers processeurs hexa-core d'AMD (Istanbul) font leur apparition au Japon fin Juin 2009 : gravés en 45 nm, avec une fréquence de 2.4 GHz, 512 Ko de mémoire cache L2 par core (3072 Ko totaux donc) et 6 Mo de cache L3 partagés (AMD Opteron 2427 à 2.2 GHz, et 2431 à 2.4 GHz).
Sun a annoncé en 2006 la sortie de son nouveau processeur l'UltraSparc T1 (Niagara) qui dispose de 8 cores.
Chaque core dispose de 4 threads d'exécution, ce qui permet sur un processeur unique d'exécuter 32 tâches simultanées exécutées en parallèle.
Le 7 août 2007, Sun annonce l'arrivée prochaine du T2 :
Connu aussi sous le nom Niagara 3, lancé officiellement durant l'Oracle Openworld à San Francisco en September 2010.
Autres solutions :
Juin 2012 : Intel vient d’officialiser ses Xeon Phi, une carte PCI-Express intégrant 50 cores x86, au moins 8 Go de GDDR5 et une version de Linux tournant indépendamment du système d’exploitation hôte. C’est l’aboutissement de son projet Knights Corner. Les processeurs seront gravés en 22 nm et utiliseront des transistors en 3D, à l’instar des Ivy Bridge. Intel parle d’une production en masse pour la fin de l’année et une mise en service des supercalculateurs utilisant son système en 2013 -- Extrait du site Tom's hardware
Prix (2013):
De combien de coeurs a t-on besoin ?
AMD fut le premier à introduire la technologie 64 bits en 2003 avec ses processeurs Athlon 64 (architecture K8). Les Athlon 64 ont pour caractéristique de pouvoir exécuter des programmes aussi bien en 32 bits qu'en 64 bits. On parle également d'architecture x86-64 (EMT64 chez Intel, AMD64 chez AMD): elle assure la compatibilité avec les applications 32 bits existantes mais laisse la possibilité de passer au 64 bits.
Un processeur est dit 32 bits ou 64 bits si ses registres généraux ont une taille de 32 ou 64 bits. Un saut technologique avait déjà été franchi lors de l'apparition du Intel 80386 qui permettait le passage du 16 bits au 32 bits.
Quel est l'intérêt de passer au 64 bits ? Les applications qui bénéficieront du passage au 64 bits sont les applications de calcul scientifique principalement.
En mode 64 bits, les 8 registres généraux passent en 64 bits (EAX devient RAX) et 8 nouveaux registres supplémentaires apparaissent (R8 à R15).
Qu'en est-il des performances de l'architecture 64 bits ?
On pourra lire à ce sujet l'article AMD K8 - Partie 3 : Architecture sur www.x86-secret.com (section Article, Rubrique CPU).
Remarque : des tests anciens (Août 2007) montrent que pour certains programmes, le passage en 64 bits permet de diminuer de 2/3 le temps d'exécution par rapport au 32 bits avec les Core 2 Duo (cf PCSTATS).
Actuellement un processeur utilise plusieurs fréquences de fonctionnement:
On peut voir le changement de fréquences en utilisant la commande suivante:
watch -n3 "cat /proc/cpuinfo | grep \"^[c]pu MHz\""
Voici quelques exemples:
Il est à noté que certains processeurs AMD Ryzen possèdent la technologie XFR (ceux estampillés X) qui permet de pousser la fréquence encore plus loin que le Turbo Boost, si la marge thermique le permet (voir XFR2)
Ceci rend les comparaisons de tests en série et en parallèle difficile puisque
Il faudra alors quand cela est possible désactiver les technologies Turbo Boost / XFR si on désire comparer ce qui est comparable.
Le 1700X possède une plage de fréquences de 3.4 à 3.8 GHz. Le premier coeur (coeur + HT) passe à la fréquence maximale mais pas les autres coeurs.
Repos | 1 Thread | 8 Threads |
1884.828 | 3643.397 | 3493.510 |
1890.453 | 3748.311 | 3493.509 |
1886.725 | 1746.701 | 3493.508 |
1882.866 | 1730.571 | 3493.508 |
1876.741 | 1744.741 | 3493.508 |
1878.985 | 1744.599 | 3493.509 |
... | ... | ... |
Le i7 4790 possède une plage de fréquences de 3.6 à 4.0 GHz. Dans le cas où on sollicite un seul coeur, tous les coeurs passent à la fréquence maximale !
Repos | 1 Thread | 4 Threads |
800.063 | 3997.950 | 3800.169 |
800.132 | 3875.932 | 3800.169 |
800.071 | 3916.942 | 3800.168 |
799.301 | 3846.592 | 3800.170 |
800.985 | 3807.581 | 3800.169 |
801.456 | 3909.223 | 3800.169 |
800.166 | 3815.121 | 3800.168 |
800.158 | 3826.660 | 3800.169 |
L'i5 7400, quant à lui, possède une plage de fréquences de 3.0 à 3.5 GHz. Cependant la fréquence maximale affichée est de 3359 Mhz !
Repos | 1 Thread | 4 Threads |
1262.578 | 3359.648 | 3299.882 |
1299.960 | 3359.609 | 3300.000 |
1234.921 | 3393.281 | 3300.000 |
1278.164 | 3380.625 | 3300.000 |
Les derniers processeurs (2018) utilisent une modulation plus fine de la fréquence :
L$'$AMD Ryzen 2700X possède une fréquence de 3,70 Ghz (allant jusqu'à 4,35 GHz en mode turbo).
Il semble aujourd'hui bien difficile de présenter brièvement la gamme des processeurs disponibles. Les critères de différenciation sont nombreux et peuvent être combinés :
voir le Intel Ark.
entrée de gamme | machine dotée d'un petit cache L2 et d'un FSB pas très véloce |
milieu de gamme | machine dotée d'un cache L2 de taille moyenne et d'un FSB rapide |
haut de gamme | machine dotée d'un cache L2 de grande taille (voire d'un cache L3) et d'un FSB rapide |
gamme mobile | machine dotée de fonctionnalités en rapport avec la gestion de l'énergie |
gamme ultra mobile | machine dotée de fonctionnalités en rapport avec la gestion très fine de l'énergie |
Chez Intel la déclinaison est la suivante :
Mesurer les performances des machines consiste à mesurer les performance du trio chipset + processeur + mémoire. D'autres tests permettent également de tester les performances de la carte graphique (élément essentiel pour les jeux 3D) ainsi que celles du disque dur.
En terme de calculs purs, SPEC (Standard Performance Evaluation Corporation) a défini un certain nombre de tests qui permettent de classer les différents processeurs.
Voici une liste de logiciels qui permettent d'évaluer les performances des machines (sous Windows XP) :
Voici quelques exemples de résultats de ces différents programmes :
Pour installer I-Nex, exécutez les commandes suivantes dans un terminal:
sudo add-apt-repository ppa:i-nex-development-team/stable
sudo apt-get update
sudo apt-get install i-nex
sudo apt-get install sysbench
Test | i5-7400 CPU @ 3.00GHz Temps (s) |
sysbench --test=cpu --cpu-max-prime=20000 run |
21.61 |
sysbench --test=cpu --cpu-max-prime=20000 --num-threads=4 run |
5.90 |
sysbench --test=memory run |
26.64 |
sysbench --test=threads run |
3.22 |
sysbench --test=threads --num-threads=4 run |
1.07 |