\chapter{Architecture\\matérielle et processus}

\section{Architecture matérielle}

\subsection{Les composants fondamentaux}
\enlargethispage*{3em}
Un appareil numérique moderne (smartphone, ordinateur, console de jeux) repose sur des composants essentiels. Ces derniers sont interconnectés pour exécuter des tâches variées.

\begin{itemize}
    \item \textbf{Processeur (CPU)} : responsable de l'exécution des instructions. Son architecture inclut plusieurs c\oe urs et une mémoire cache optimisant les performances.
    \item \textbf{Mémoire vive (RAM)} : stocke temporairement les données et instructions en cours d'utilisation. Son accès est bien plus rapide que celui du stockage permanent.
    \item \textbf{Stockage} : permet la conservation des données sur des supports variés : SSD (rapide, sans pièce mécanique) et HDD (capacité importante).
    \item \textbf{Carte mère} : connecte et assure la communication entre les composants via des bus de données et des interfaces comme PCIe ou SATA.
    \item \textbf{Périphériques} : dispositifs d'entrée (clavier, souris) et de sortie (écran, imprimante) facilitent l'interaction avec l'utilisateur.
    \item \textbf{Contrôleur vidéo et accélérateur graphique}:\index{GPU} nommé généralement GPU (Graphics Processing Unit), il s'agit d'un processeur à part entière et de son microenvironnement minimal (mémoire de travail, bus de communication) qui composent le contrôleur graphique.
\end{itemize}

\subsection{Les SoCs (System on Chip)}
\index{SoC}

Depuis les débuts de l'informatique, les composants électroniques n'ont cessé:
\begin{itemize}
\item de gagner en performances (augmentation de la puissance de traitement),
\item de se miniaturiser,
\item de devenir accessibles au plus grand nombre (diminution des coûts de production).
\end{itemize}

La miniaturisation a atteint de telles proportions qu'il est aujourd'hui possible de réunir au sein d'une seule puce électronique tous les composants vitaux d'un ordinateur (CPU, RAM, mémoire de stockage, bus de communications, contrôleurs, GPU, interconnexions,...). Ces \og ordinateurs-puce \fg s'appellent des SoCs.

\begin{defin}
Un \textit{SoC} (System On Chip) est un système intégré sur une unique puce électronique qui regroupe les différents composants d'un ordinateur tels que le processeur, la mémoire, les interfaces et bus de communication, etc.
\end{defin}

\enlargethispage*{3em}

Les avantages des SoCs sont multiples.

\begin{itemize}
\item\textit{Faible encombrement} (juste une puce électronique), qui leur permet d'être implantés dans des appareils de taille réduite (téléphone, montre,...). L'avènement des smartphones est à l'origine de leurs succès.

\item \textit{Faible consommation énergétique d'un SoC due à la miniaturisation des composants.} Il y a moins de pistes que sur une carte mère, les distances sont raccourcies, il n'y a pas besoin de connecteur ni de câble et la tension d'alimentation peut être réduite. On obtient ainsi moins de dissipation thermique et de pertes par effet Joule.

\item \textit{Baisse des coûts de fabrication et d'industrialisation} car ils sont produits en très grande quantité et ne nécessitent pas d'assemblage manuel des éléments qui les composent. Tous les composants électroniques sont gravés en une seule fois au sein d'une unique puce. 
\end{itemize}

\enlargethispage*{\baselineskip}

Il y a cependant quelques inconvénients : les éléments qui composent un SoC étant gravés ensemble, il n'est pas possible de les faire évoluer individuellement. On ne pourra pas changer la \og carte réseau \fg ni la \og carte graphique\fg par exemple.

\Par

En conséquence, la durée de vie et la fiabilité d'un SoC sont celles de son maillon le plus faible. Le premier élément d'un SoC à présenter un dysfonctionnement provoquera une altération complète du SoC, qui ne pourra pas être réparé par remplacement de l'élément défaillant.

\begin{aretenir}
\begin{itemize}
\item Un processeur multi-cœur exécute autant d'instructions par cycle qu'il a de cœur.

\item La consommation électrique et l'échauffement augmentent avec la fréquence d'exécution.

\item Tous les programmes en cours d'exécution et les données qu'il manipule sont recopiés et \og travaillés \fg dans la RAM.

\item Il existe un grand nombre de contrôleurs spécifiques, dédiés aux fonctionnalités assumées par la machine et au pilotage des périphériques. Ils déchargent le processeur (CPU) des opérations routinières.

\item Un SoC (System on Chip) est une puce unique qui embarque tous les éléments de base d'un ordinateur.
\end{itemize}
\end{aretenir}

\section{Processus et ressources partagées}
\index{Processus}

\enlargethispage*{3em}
\begin{problematique}
Comment un système d'exploitation multitâche fait-il pour exécuter de nombreux programmes simultanément alors que la machine ne possède qu'un seul et unique processeur avec un nombre de cœurs très limité ?
\end{problematique}

\subsection{Partage du temps d'exécution}

Un ordinateur semble capable d'exécuter simultanément plusieurs programmes : une vidéo en lecture, un téléchargement en cours, un traitement de texte ouvert et une impression en arrière-plan. Pourtant, un processeur ne peut traiter qu'un nombre limité d'instructions en parallèle, correspondant au nombre de ses cœurs.

Pour donner l'illusion du multitâche, le système d'exploitation divise le temps de calcul du processeur en courtes séquences et alterne rapidement entre les programmes en cours. Ce mécanisme assure un partage efficace des ressources.

Afin d'assurer cette gestion, le système d'exploitation ne manipule pas directement les programmes, mais des processus, qui sont les unités d'exécution associées à chaque programme lancé.

\subsubsection{Processus}
\begin{defin}
Un processus est une instance d'un programme en cours d'exécution, accompagnée de son contexte d'exécution : le code du programme, la mémoire allouée, ressources utilisées (fichiers, ports, etc.) et l'état des registres du processeur.
\end{defin}

Le système d'exploitation identifie chaque processus par un nombre entier unique appelé \textit{PID} (process identification, en anglais). À chaque processus est associé un \textit{PPID} qui est le PID du processus parent qui a lancé le processus. Sous Linux, la commande \texttt{ps} permet d'afficher les processus associés au terminal courant. La commande \texttt{kill nnn} envoie un signal pour terminer le processus de PID \texttt{nnn}.

\subsubsection{\'Etat d'un processus}

À un instant donné, un processus peut être dans l'un des états standards suivants :
\begin{itemize}%[label=$\bullet$]
	\item \textbf{nouveau} (\textit{created} ou \textit{new}) : en cours de création par le système d'exploitation. C'est un état transitoire par lequel le processus ne passe qu'une fois ;
	\item \textbf{prêt} (\textit{ready} ou \textit{runnable}) : il est en attente d'exécution ;
	\item \textbf{élu} ou \textbf{en exécution} (\textit{running}) : le processus est en train de s'exécuter ;
	\item \textbf{en attente} (\textit{blocked} ou \textit{waiting}) : suspendu, en attente d'un événement externe ;
	\item \textbf{terminé} (\textit{terminated}) : fin d'exécution. Le système d'exploitation est en train de désallouer les ressources utilisées. C'est aussi un état transitoire.
\end{itemize}

\begin{figure}
\begin{center}
\includegraphics{274_07-etats-03-2}
\figcaption{Les différents états d'un processus\\dans un ordonnancement à court terme}
\end{center}
\end{figure}

Un processus alterne continuellement entre les états \textbf{prêt}, \textbf{en exécution} et \textbf{en attente}, selon les décisions du système d'exploitation.

%% @TODO ajouter un encart sur la gestion des processus sous Linux

\subsection{Ordonnancement}
\index{Ordonnanceur}

L'ordonnancement (\textit{scheduling}) des processus est un mécanisme essentiel au fonctionnement multitâche. Le système d'exploitation attribue le temps d'exécution aux processus en fonction de divers critères.

\begin{defin}[ordonnanceur]
L'\textbf{ordonnanceur} (\textit{scheduler}) est le module du système d'exploitation responsable de la gestion des processus en cours d'exécution. Il décide quel processus obtient l'accès au processeur à un instant donné en fonction de divers critères comme les priorités, le temps d'exécution et l'état des processus (prêt ou élu).
\end{defin}

Différents algorithmes d'ordonnancement existent :
\begin{itemize}
\item \textbf{non préemptifs} : un processus s'exécute jusqu'à son blocage ou sa fin ;
\item \textbf{préemptifs} : l'ordonnanceur peut interrompre un processus pour exécuter un autre.
\end{itemize}

%
%Pour cela, il met en œuvre des stratégies d'ordonnancement qui assurent un partage efficace et équitable des ressources, en gérant le changement de contexte et la répartition du temps d'exécution entre les processus actifs.
%
%Il existe plusieurs stratégies d'ordonnancement visant à optimiser l'ordre d'exécution des processus. On distingue principalement deux types d'algorithmes : les algorithmes préemptifs, où l'ordonnanceur peut interrompre un processus en cours d'exécution pour en exécuter un autre, en fonction de critères comme le quantum de temps ou la priorité, et les algorithmes non préemptifs, où un processus conserve l'accès au processeur jusqu'à ce qu'il se termine ou se bloque en attente d'une ressource.

\subsubsection{Algorithmes non-préemptifs}

Un algorithme d'ordonnancement non préemptif n'effectue aucune réquisition. Les processus rendent la main seulement \og de leur plein gré \fg, quand ils passent à l'état bloqué ou terminé, mais ne peuvent être interrompus par le système d'exploitation tant qu'ils sont à l'état élu (en cours d'exécution).

\paragraph{First Come, First Served (FCFS)}

C'est la stratégie du \og premier arrivé, premier servi \fg, qui fonctionne comme une file (FIFO). Les processus sont placés dans une file d'attente dans leur ordre d'arrivée et le premier lancé est exécuté en continu jusqu'à ce qu'il se termine ou devienne bloqué. Le processus bloqué est replacé dans la file, en dernière position. C'est ensuite le processus prêt suivant dans la file qui s'exécute. Cette stratégie est simple à implémenter mais peut provoquer des attentes longues si un processus long est en tête de file.

\paragraph{Shortest Job First (SJF)}

Avec cette stratégie, on évalue la durée supposée de traitement de chacun des processus existants. Le processus qui a la durée d'exécution la plus courte est alors prioritaire, ce qui permet de réduire le temps d'attente moyen des processus. Toutefois, cette approche suppose une estimation fiable de la durée de chaque processus, ce qui n'est pas toujours réalisable.

\begin{defins}
On appelle \textit{temps d'attente} d'un processus la durée qui s'écoule entre la soumission du processus (arrivée) et le \textit{début} de son exécution.

On appelle \textit{temps de séjour} (ou temps de réponse) d'un processus la durée qui s'écoule entre la soumission du processus et la \textit{fin} de son exécution.

De plus, on peut calculer un \textit{temps d'attente moyen} et un \textit{temps de séjour moyen} pour l'ensemble des processus.
\end{defins}

\subsubsection{Algorithmes préemptifs}

Un algorithme d'ordonnancement préemptif peut reprendre la main lors de l'exécution d'un processus et exécuter un autre processus (prioritaire sur le précédent ou plus court, etc.). 

\paragraph{Shortest Remaining Time (SRT)}

C'est une évolution de la stratégie \textit{Shortest Job First} où l'on tient compte cette fois, non pas de la durée totale (supposée) d'exécution de chaque processus, mais du temps restant estimé : à tout instant, le processus ayant le moins de temps restant à exécuter est choisi en priorité. Ainsi, un processus de durée d'exécution très courte peut devenir prioritaire alors qu'un processus dont il reste davantage de temps de traitement est déjà en train de s'exécuter.

\paragraph{Tourniquet ou \textit{Round Robin} (RR)}

Dans l'algorithme du tourniquet, chaque processus dispose d'un quantum de temps. Chacun des processus est alors exécuté à tour de rôle, avec cette durée. Les processus prêts sont stockés dans une file (FIFO).

C'est l'algorithme le plus couramment utilisé dans les OS multitâches, principalement pour sa simplicité et sa fiabilité. En général, il est complété par un mécanisme d'ordonnancement avec priorité (\textit{cf}. ci-après).

\begin{defin}[quantum de temps]
On appelle quantum de temps la plus petite unité de temps qu'un système d'exploitation peut attribuer à un processus.
\end{defin}

Cette durée, généralement fixe, définit l'intervalle de temps minimal durant lequel un processus peut s'exécuter avant une éventuelle interruption. Un processus peut se voir allouer plusieurs quanta consécutifs. Typiquement, un quantum de temps dure entre 20 et 50 ms suivant l'OS et l'algorithme d'ordonnancement utilisé.

\subsubsection{Ordonnancement avec priorité}

Chaque processus se voit attribuer une valeur de priorité, cette priorité pouvant évoluer de façon dynamique. Les processus de même niveau de priorité sont regroupés dans une file (FIFO) et ordonnancés avec l'algorithme du tourniquet (\textit{Round Robin}). L'ordonnanceur sélectionne alors le processus de priorité la plus élevée et qui est en tête de sa file. Pour éviter qu'un processus prioritaire ne monopolise indéfiniment le processeur, la priorité des processus en cours d'exécution est périodiquement diminuée, tandis que la priorité des processus en attente peut être augmentée.

\subsection{Interblocage (deadlock)}
\index{Deadlock}
\index{Interblocage}

Supposons deux processus concurrents \textit{P1} et \textit{P2}. Ils ont accès à deux ressources, A et B, qui ne sont initialement utilisées par aucun processus.

Le processus \textit{P1} accède alors à la ressource A (elle est alors verrouillée pour l'usage exclusif de \textit{P1}). En suite, le processus \textit{P2} accède à la ressource B (qui était libre et qui devient verrouillée).

Il est ensuite possible que le processus \textit{P1} ait besoin d'accéder la ressource B qui est prise par \textit{P2}. Dans ce cas, \textit{P1} est \textit{bloqué} jusqu'à ce que \textit{P2} ait libéré la ressource B.

Supposons que le processus \textit{P2} ait besoin d'accéder à la ressource A. Comme elle est actuellement verrouillée par \textit{P1}, \textit{P2} passe dans l'état \textit{bloqué} jusqu'à ce que \textit{P1} ait libéré la ressource A. Sauf que \textit{P1} est déjà bloqué et ne peut être débloqué tant que \textit{P2} n'a pas terminé.

Cette situation provoque un blocage réciproque de \textit{P1} et de \textit{P2} qui s'attendent\linebreak mutuellement. On appelle cette situation un interblocage. C'est une situation que l'on cherche évidemment à éviter.

\begin{defin}[interblocage]
On appelle \textit{interblocage} (deadlock en anglais) un état obtenu en programmation concurrente lorsqu'au moins deux processus s'attendent mutuellement. 
\end{defin}


%\Par
%
%\begin{figure}
%\begin{center}
%\includegraphics{283_08-dead-lock}
%\figcaption{Exécution avec et sans interblocage}
%\end{center}
%\end{figure}


%
%\NathanLiveVideo[\PictoVideo\ Retrouvez une vidéo de présentation des processus.]{requêtes SQL}{https://media.prepamath.fr/ILTNSIch08crs01}
%
%\qrset{height=1.1cm,version=5}\rput(-1,0.5){
%\psframebox{\qrcode{https://media.prepamath.fr/ILTNSIch08crs01}}}
%\vspace*{-10pt}


