add PCR, ALP

This commit is contained in:
Klagarge committed 2024-03-24 16:45:01 +01:00
1 parent 991f49776d
commit 5a1314a97a
3 files changed
+197 -5

No files matched your search

+197 -5
View File
@@ -20,8 +20,8 @@ Cela permet d'éviter de bloquer toutes les applications lorsqu'une seule est en
La programmation concurrente sur plusieurs CPU permet en plus un gain de temps.
# Exclusion mutuelle
un programme est une entité statique
un processus est une entité dynamique
- un programme est une entité statique qui contient des processus
- un processus est une entité dynamique (il s'agit d'une tâche en cours d'exécution)
Les processus ne sont jamais totalement indépendants.
Ils partagent des ressources (mémoire, fichiers, périphériques, variable, etc.)
@@ -196,7 +196,7 @@ Sinon, **un** processus peut modifier la ressource et aucun peut lire.
```cpp
void BeginRead(void) {
osSemaphoreAcquire(rw, osWaitForever);
osSemaphoreAcquire(mutexNbReader, osWaitForever); // ENTER CRITICAL SECTION
osSemaphoreAcquire(mutexNbReader, osWaitForever); // ENTER CRITICAL SECTION
nbReader++;
if(nbReader == 1) osSemaphoreAcquire(w, osWaitForever);
osSemaphoreRelease(mutexNbReader); // EXIT CRITICAL SECTION
@@ -221,13 +221,98 @@ void EndWrite(void) {
}
```
# Coopération-Synchronisation
La coopération entre processus implique la synchronisation entre eux pour éviter de ressource.
## Évènement
L'évènement est un outil permettant de résoudre un problème de synchronisation comme les sémaphores ou les mutex.
On peut manipuler les évènements :
- ***Wait()*** : Attendre un évènement
- ***Signal()*** : Déclencher un évènement
- ***Init()*** : Initialiser un évènement
On peut aussi résoudre un problème de synchronisation entre processus avec un sémaphore initialisé à 0. On peut le comparer
à une barrière déclenchable depuis un autre processus.
# Synchronisation
Les sémaphores ne permettent pas de résoudre tous les problèmes de synchronisation. Trop grand risque de DEADLOCK.
Il faut utiliser d'autres outils plus performants.
## Le moniteur (monitor)
On peut l'imager avec une classe entièrement protégée par des sémaphores pour l'accès au variable et fonction (procédure).
Etat d'un processus :
Le moniteur possède comme primitive :
- ***x.wait*** : bloque le processus jusqu'à ce qu'un x.send soit émis.
- ***x.send*** : débloque le processus qui attend sur un x.wait.
```pascal
monitor M;
defines DepositeChar, TakeChar;
var
c : char;
chAvailable : boolean;
x : signal;
procedure TakeChar(var ch:char);
begin
if not chAvailable then x.wait end if;
ch := c;
chAvailable := FALSE
end TakeChar;
procedure DepositeChar(ch:char);
begin
c := ch;
chAvailable := TRUE;
x.send
end DepositeChar;
begin
chAvailable := FALSE
end M;
```
```pascal
process Keyboard;
uses M;
var cRead: char;
begin
...
Read a character on keyboard
Put it in the cRead variable
M.DepositeChar(cRead);
...
end Keyboard;
process Screen;
uses M;
var cWrite: char;
begin
...
M.TakeChar(cWrite);
Write the character cWrite on the screen
...
end Screen;
```
## Producteurs / consommateurs
Le problème survient lorsque le producteur envoie un message au consommateur via une queue.
[Example](https://git.kb28.ch/Klagarge/PTR-Queue/src/branch/master/main.c)
- ***Le producteur*** (Producer) doit être mis en attente s'il veut déposer un message alors que le tampon est plein
- ***Le consommateur*** (Consumer) doit être mis en attente s'il veut prélever un message alors que le tampon est vide
- ***Le producteur*** (Producer) en attente doit être débloqué dès que le consommateur (Consumer) prélève un message
- à ce moment le tampon n'est plus plein
- ***Le consommateur*** (Consumer) en attente doit être débloqué dès que le producteur (Producer) dépose un message
- à ce moment le tampon n'est plus vide
On peut résoudre aisément le problème producteurs-consommateurs avec un moniteur ainsi qu'avec un sémaphore.
<b><u>Solution à chier :</u></b><br>
Le producteur attend que le consommateur soit capable de réceptionner le message, ainsi les deux peuvent
continuer leurs exécutions (principe de rendez-vous). Ce concept ne possède pas de buffer.
# Allocation processeur
État d'un processus :
![img_1.png](img_1.png)
@@ -238,3 +323,110 @@ contiennent le registre de status et un pointeur sur sa stack. Ils sont utilisé
3. Il va prendre le descripteur du prochain processus et utiliser ses registres.
4. Le processus continue jusqu'au nouveau switching context.
## Cycle processeur
Un processeur réalise alternativement une suite de :
- ***Cycles processeur*** (CPU burst cycle)
- ***Cycles d'entrée-sortie*** (I/O burst cycle)
Lorsque le temps de cycle processeur est petit et qu'il y a une attente engendrée par les entrées-sorties, il est pertinent de partager
le processeur entre plusieurs processus.
## Queues d'ordonnancement
Les processus en attente du processeur sont placés dans une liste appelée **queue de processus prêts** (ready queue).
Cette queue peut être gérée comme une file FIFO, une liste de priorité, un arbre, une pile, une liste non-ordonnée, etc.
Cette queue est sous forme d'une liste chaînée qui contient des pointeurs sur les descripteurs de processus.
Les processus qui ont besoins d'une ressource sont placés dans une liste d'attente correspondant à la ressource (mutex/sémaphore).
L'ensemble des queues peut être regroupé dans le diagramme de synthèse suivant :
![synthese_diagram_queue_process.png](medias/synthese_diagram_queue_process.png)
## Ordonnanceurs
![ordonnanceur.png](medias/ordonnanceur.png)
### Ordonnanceur à court terme
- Sélectionne un nouveau processus toutes les millisecondes.
- Doit être très rapide
- Est très simple
### Ordonnanceur à long terme
- Contrôle le degré de multiprogrammation, c'est-à-dire, le nombre de processus en mémoire.
- Assure que la charge globale du processeur soit répartie équitablement entre les processus réalisant beaucoup d'entrée-sorties et les
processus réalisant beaucoup de calculs.
- S'exécute peu fréquement
- La complexité de ce dernier augmente fortement.
### Le swapping
On peut augmenter la RAM avec de la mémoire virtuelle (swap) pour garder les processus et ne pas les mettre en stockage
long termes.
### Distributeur de tâches
Il distribue au processeur les processus sélectionnés par l'ordonnanceur court terme.
- Il charge les registres du processus sélectionné
- Il change en mode utilisateur depuis le superviseur. Ce dernier servant à modifier les registres.
- Il met à jour le PC
## Critères de performance
- ***Efficacité** (CPU utilisation) : Taux d'utilisation du processus
- ***Débit*** (troughtput) : Nombre de processus par unité de temps
- ***Temps global*** (turnaround time) : Temps qui s'écoule entre la soumission du processus et la fin de son exécution
- ***Temps d'attente*** (waiting time) : Temps d'attente d'un processus dans la queue des processus prêts
- ***Temps de réponse*** (response time) : intervalle de temps entre l'heure de soumission et l'heure de la première réponse
## Algorithme d'ordonnancement
L'allocateur du processeur doit sélectionner quels processus situés dans la queue des processeurs prêts doivent recevoir le processeur.
### FIFO
L'algorithme FIFO est le plus simple. Il sélectionne le premier processus de la queue des processus prêts. Mais, il n'est
pas forcément le plus efficace.
### Le plus court d'abord
Le processus avec la plus petite suite d'instruction est exécuté en premier. Si deux processus ont le même nombre d'instructions,
on peut utiliser un algorithme FIFO pour déterminer le vainqueur. Il est performant, mais c'est compliqué de connaître
le nombre d'instructions.
Il nécessite d'éstimer en temps réel la longueur du processus.
$$\tau_{n+1} = \alpha\cdot t_{n}+(1-\alpha)\cdot \tau_{n}$$ <br>
$\tau_{n+1}$ : prochaine valeur estimée <br>
$\alpha$ : coefficient de pondération $0\leq\alpha\leq 1$ <br>
$t_{n}$ : valeur mesurée à l'instant $n$ <br>
$\tau_{n}$ précédente valeur estimée pour l'instant $n$ <br>
### Priorité
Cet algorithme donne au processeur le processus qui a la plus haute priorité qui est défini par l'utilisateur.
On peut rencontrer plusieurs problèmes :
- ***Blocage indéfini*** (indefinite blocking) : on reste bloqué dans un processus de haute priorité.
- ***Famine*** (starvation) : Les processus de basse priorité ne sont jamais exécuté.
***Solution*** : On augmente la priorité dum processus en attente tous les quantums de temps.
### Ordonnancement avec réquisition (preemptive)
On réévalue l'ordre des processus dans la queue à chaque tick et le processus élu prend ou garde le processeur.
### Tourniquet (round-robin)
Il est basé sur une tranche de temps fixe soit quantum de temps. On donne à chacun des processus ce temps et on passe au
processus suivant une fois le temps écoulé.
Lorsque le temps est grand, on retrouve en quelque sorte une FIFO, car le temps d'exécution des processus est plus court que
le quantum de temps.
Si le temps est très petit, le tourniquet est appelé **processeur partagé** (processor sharing).
<b><u>Overhead</u></b> : temps perdu pour changer de processus.<br>
### Files multiples (multi-queue)
On utilise cette technique lorsqu'on peut facilement classer les processus en différents groupes. Chaque queue possède son
propre algorithme d'ordonnancement. Un ordonnancement entre les queues est réalisé soit par priorité et réquisition, soit
en round robin.
### Files multiples imbriquées (multi-level feedback queue)
Cette technique permet aux processus d'évoluer dans des queues en fonction du temps d'exécution écoulé.
- Un processus entrant dans la queue des processus prêts est placé dans la queue 0
- Si le quantum est écoulé et que la suite d’instruction processeur n’est pas terminée, le processus est placé dans
la queue de priorité inférieure
Plus on descend dans les queues plus on est de priorité basse.
<u>Exemple :</u> Plus on descend dans les queues, plus le quantum devient grand.
# Interblocage
Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB