This repository has been archived on 2024-05-05. You can view files and clone it, but cannot push or open issues or pull requests.
work-stealing-scheduler/report/document.tex

313 lines
12 KiB
TeX
Raw Normal View History

2024-04-25 13:08:09 +02:00
\DocumentMetadata{testphase = {phase-II,sec,toc,graphic,minipage,text}}
\documentclass[a4paper]{article}
\usepackage[T1]{fontenc} % encoding
\renewcommand{\familydefault}{\sfdefault} % sans-serif font
2024-03-26 21:08:43 +01:00
% Add \extra info to title
2024-03-26 21:01:09 +01:00
\makeatletter
\providecommand{\extra}[1]{
\apptocmd{\@author}{
\end{tabular}
2024-03-26 21:08:43 +01:00
\par\vspace*{0.7em}
2024-03-26 21:01:09 +01:00
\begin{tabular}[t]{c}
#1}{}{}
}
\makeatother
2024-04-21 10:19:54 +02:00
% Code integration
2024-04-23 13:25:28 +02:00
\usepackage{minted}
\setminted[c]{autogobble,frame=lines}
\usemintedstyle{emacs}
2024-04-21 10:19:54 +02:00
% Langages
\usepackage[french]{babel}
\frenchsetup{SmallCapsFigTabCaptions=false}
\usepackage{csquotes}
\MakeOuterQuote{"}
2024-04-25 02:43:13 +02:00
% Images
\usepackage{graphicx}
2024-04-25 13:10:51 +02:00
\usepackage{caption}
\captionsetup{justification=centering}
2024-04-25 02:43:13 +02:00
2024-04-21 10:04:30 +02:00
\def\titleName{Projet : Un ordonnanceur par work stealing}
\def\docTitle{\href{https://www.irif.fr/~jch/enseignement/systeme/projet.pdf}{\titleName}}
\def\anri{Anri Kennel}
2024-04-21 10:19:54 +02:00
\def\authorMail{mailto:anri.kennel@etu.u-paris.fr}
2024-04-21 10:04:30 +02:00
\def\docSubject{Programmation système avancée}
\def\docLocation{Université Paris Cité}
\usepackage[
pdfauthor={\anri}, % author metadata
pdftitle={\titleName}, % title metadata
pdfsubject={\docSubject}, % subject metadata
hidelinks, % clickable links in table of contents
]{hyperref}
2024-03-26 21:01:09 +01:00
2024-04-21 10:04:30 +02:00
\title{\docTitle}
\author{\href{\authorMail}{\anri}\thanks{\anri : 22302653}}
\extra{\docSubject~$\cdot$ \docLocation}
\date{Année universitaire 2023-2024}
2024-04-21 11:57:37 +02:00
\newcommand{\docref}[1]{\textit{\nameref{#1}}} % italic nameref
% Aliases
\def\coeur{c\oe{}ur}
2024-04-25 02:43:13 +02:00
\def\mone{\textit{Machine 1}} % fixe
\def\mtwo{\textit{Machine 2}} % portable
\def\bone{\textit{Benchmark quicksort}}
\def\btwo{\textit{Benchmark mandelbrot}}
\def\ws{\enquote{work-stealing}}
2024-03-26 21:01:09 +01:00
\begin{document}
\maketitle
2024-04-21 10:19:54 +02:00
\flushbottom
\tableofcontents
\clearpage
2024-04-21 11:57:37 +02:00
\section{Descriptions}
Description des différents algorithmes implémentés.
2024-04-25 02:13:56 +02:00
\subsection{Séquentiel}
2024-04-23 13:25:28 +02:00
Cette implémentation naïve correspond au mode \texttt{serial}
de \texttt{quicksort.c}. Elle lance les tâches sans threads.
2024-04-21 11:57:37 +02:00
2024-04-23 13:25:28 +02:00
\subsection[Threads sans gestion]{Threads sans gestion}
2024-04-21 11:57:37 +02:00
Cette implémentation correspond à simplement démarrer un nouveau thread
pour chaque nouvelle tâche.
2024-04-25 13:30:46 +02:00
Comme cette implémentation n'ordonnance rien et que le nombre de threads créés
2024-04-23 13:25:28 +02:00
est important.
2024-04-21 11:57:37 +02:00
\subsection{Threads avec pile}\label{desc:th_pile}
2024-04-25 13:30:46 +02:00
Pour cette implémentation, nous gardons en mémoire une pile et nous démarrons
un nombre fixe de threads, et à chaque ajout d'une tâche, le thread l'empile.
Chaque thread récupère la dernière tâche ajoutée à la pile.
2024-04-21 11:57:37 +02:00
\subsubsection{Sélection aléatoire de tâche}
Même fonctionnement que dans l'algorithme de \docref{desc:th_pile}, sauf
2024-04-25 13:18:47 +02:00
qu'au lieu de récupérer la dernière tâche, le thread récupère une tâche
2024-04-21 11:57:37 +02:00
aléatoire de la pile.
\subsection{Répartition par \ws}\label{desc:ws}
2024-04-25 13:30:46 +02:00
Ici, chaque \coeur~a sa propre liste de tâches. Quand un thread n'a
plus de tâches, il essaie d'en voler une à un autre thread.
2024-04-25 02:43:13 +02:00
\section{Comportement}
\subsection{Listes}
Dans l'ordonnanceur LIFO, la liste est une pile. Chaque thread récupère le
premier élément de la pile, c'est-à-dire le dernier à avoir été ajouté.
Avec la répartition par \ws, la liste est une deque. Comme dans l'ordonnanceur
LIFO, chaque thread récupère le premier élément de la deque, mais quand il y a
un vol, c'est le dernier élément qui est récupéré par le thread.
\subsection{Synchronisations}
Dans mes implémentations, j'ai exclusivement utilisé des mutex ainsi que des
variables de conditions pour endormir/réveiller mes threads.
2024-04-25 13:30:46 +02:00
Pendant le développement, j'ai parfois utilisé \texttt{usleep} au lieu des
2024-04-25 13:18:47 +02:00
variables de conditions pour faire attendre les threads, mais j'ai obtenu de
2024-04-25 13:30:46 +02:00
meilleurs résultats avec les variables de conditions. Aussi, je pense qu'avoir
2024-04-25 13:18:47 +02:00
les variables de conditions m'assure que mon ordonnanceur fonctionne sur
n'importe quel CPU, qu'il soit lent ou rapide, avec des performances honnêtes.
En effet, choisir une valeur qui fonctionne bien sur mon ordinateur n'assure pas
qu'elle soit la meilleure pour un autre.
\subsection{Nombre de threads}
Pour avoir un programme performant, il faut équilibrer le nombre de threads par
rapport aux nombres de \coeur{}s disponibles. Il faut également équilibrer la
création de nouvelles tâches par thread par rapport au véritable travail
2024-04-25 13:30:46 +02:00
effectué par ledit thread. Par exemple, dans le \btwo, chaque tâche soit crée
quatre nouvelles tâches, soit calcule une portion de l'image. Une plus grande
création de tâches favorise le \ws~parce qu'une pile unique atteint ses limites
quand trop de tâches sont ajoutées, car les threads n'ont pas le temps
"d'abattre le travail" assez rapidement.
2024-04-21 11:57:37 +02:00
2024-04-25 02:43:13 +02:00
\section{Statistiques}
2024-04-25 02:13:56 +02:00
Chaque implémentation a été testée avec l'optimisation de niveau 2
de \texttt{gcc}, sur 2 machines.
2024-04-21 11:57:37 +02:00
\begin{enumerate}
\item \textbf{12 \coeur{}s} pour la \mone.
\item \textbf{8 \coeur{}s} pour la \mtwo.
2024-04-21 11:57:37 +02:00
\end{enumerate}
2024-04-25 13:30:46 +02:00
Le programme utilisé pour tester les implémentations est le quicksort fourni
et une adaptation de mandelbrot fournie dans le TP10.
2024-04-25 02:13:56 +02:00
\subsection{Séquentiel}\label{stats:seq}
2024-04-21 11:57:37 +02:00
\begin{description}
2024-04-25 02:13:56 +02:00
\item[\bone] \hspace{1em}
\begin{description}
\item[\mone] Le programme a été lancé \textbf{100 fois}.
Le temps moyen d'exécution a été de \textbf{0,855 secs}
\item[\mtwo] Le programme a été lancé \textbf{100 fois}.
Le temps moyen d'exécution a été de \textbf{1,139 secs}
\end{description}
\item[\btwo] \hspace{1em}
\begin{description}
\item[\mone] Le programme a été lancé \textbf{10 fois}.
Le temps moyen d'exécution a été de \textbf{3,733 secs}
\item[\mtwo] Le programme a été lancé \textbf{10 fois}.
Le temps moyen d'exécution a été de \textbf{6,020 secs}
\end{description}
2024-04-21 11:57:37 +02:00
\end{description}
2024-04-25 02:13:56 +02:00
2024-04-21 11:57:37 +02:00
Ce programme ne bénéficie pas de toute la puissance de la machine.
\subsection{Threads sans gestion}\label{stats:th_ges}
2024-04-25 02:13:56 +02:00
2024-04-21 11:57:37 +02:00
\begin{description}
2024-04-25 02:13:56 +02:00
\item[\bone] \hspace{1em}
\begin{description}
\item[\mone] Le programme a été lancé \textbf{10 fois}.
Le temps moyen d'exécution a été de \textbf{35,985 secs}
\item[\mtwo] Le programme a été lancé \textbf{10 fois}.
Le temps moyen d'exécution a été de \textbf{18,854 secs}
\end{description}
\item[\btwo] \hspace{1em}
\begin{description}
\item[\mone] Le programme a été lancé \textbf{10 fois}.
Le temps moyen d'exécution a été de \textbf{66,078 secs}
\item[\mtwo] Le programme a été lancé \textbf{10 fois}.
Le temps moyen d'exécution a été de \textbf{41,060 secs}
\end{description}
2024-04-21 11:57:37 +02:00
\end{description}
2024-04-25 13:30:46 +02:00
La création des threads pour chaque tâche crée un énorme
2024-04-21 11:57:37 +02:00
goulot d'étranglement qui réduit de grandement les performances.
2024-04-23 13:25:28 +02:00
Le temps d'exécution étant long, nous pouvons voir les threads via la commande
\texttt{top} : \mintinline{bash}|top -Hp $(pgrep ordonnanceur)|.
2024-04-25 13:30:46 +02:00
Pour augmenter les performances, il faut avoir une taille fixe de threads crée,
2024-04-23 13:25:28 +02:00
et donc il faut gérer les tâches et décider de quelle tâche va sur quel thread.
\subsection{Threads avec pile}\label{stats:stack}
2024-04-21 11:57:37 +02:00
\begin{description}
2024-04-25 02:13:56 +02:00
\item[\bone] \hspace{1em}
\begin{description}
\item[\mone] Le programme a été lancé \textbf{100 fois}.
Le temps moyen d'exécution a été de \textbf{0,258 secs}
\item[\mtwo] Le programme a été lancé \textbf{100 fois}.
Le temps moyen d'exécution a été de \textbf{0,356 secs}
\end{description}
\item[\btwo] \hspace{1em}
\begin{description}
\item[\mone] Le programme a été lancé \textbf{100 fois}.
Le temps moyen d'exécution a été de \textbf{0,787 secs}
\item[\mtwo] Le programme a été lancé \textbf{100 fois}.
Le temps moyen d'exécution a été de \textbf{1,858 secs}
\end{description}
2024-04-21 11:57:37 +02:00
\end{description}
2024-04-25 13:30:46 +02:00
Le lancement de nouveaux threads étant limité, les performances
2024-04-21 11:57:37 +02:00
sont grandement améliorées par rapport aux tests de \docref{stats:th_ges}.
2024-04-25 13:30:46 +02:00
Également, grâce au fait que désormais nous utilisons les \coeur{}s~de notre CPU,
2024-04-21 11:57:37 +02:00
les performances sont aussi améliorées par rapport aux tests de
2024-04-25 02:13:56 +02:00
\docref{stats:seq}.
2024-04-21 11:57:37 +02:00
2024-04-25 13:18:47 +02:00
Dans la \autoref{fig:btm-lifo}, nous observons que les \coeur{}s du CPU ne sont pas
2024-04-25 13:30:46 +02:00
tous utilisés à 100 \%. Ceci est dû au fait que l'accès à la liste des tâches est
limité, car partagé entre les threads.
2024-04-25 02:43:13 +02:00
\begin{figure}[h!]
\centering
2024-04-25 02:53:29 +02:00
\includegraphics[alt={Graphique},width=\textwidth]{imgs/bottom-lifo.jpg}
2024-04-25 02:43:13 +02:00
\caption{Utilisation ressources sur la \mone~avec \docref{desc:th_pile}}
\label{fig:btm-lifo}
2024-04-25 02:43:13 +02:00
\end{figure}
2024-04-21 11:57:37 +02:00
\subsubsection{Sélection aléatoire de tâche}
\begin{description}
2024-04-25 02:13:56 +02:00
\item[\bone] \hspace{1em}
\begin{description}
\item[\mone] Le programme a été lancé \textbf{100 fois}.
Le temps moyen d'exécution a été de \textbf{0,390 secs}
\item[\mtwo] Le programme a été lancé \textbf{100 fois}.
Le temps moyen d'exécution a été de \textbf{0,438 secs}
\end{description}
\item[\btwo] \hspace{1em}
\begin{description}
\item[\mone] Le programme a été lancé \textbf{100 fois}.
Le temps moyen d'exécution a été de \textbf{0,438 secs}
\item[\mtwo] Le programme a été lancé \textbf{100 fois}.
Le temps moyen d'exécution a été de \textbf{1,887 secs}
\end{description}
2024-04-21 11:57:37 +02:00
\end{description}
2024-04-23 13:25:28 +02:00
Cette implémentation est identique à \docref{stats:stack}, à l'exception que
2024-04-25 13:18:47 +02:00
les threads récupèrent une tâche aléatoire de la pile au lieu d'y prendre
2024-04-25 13:30:46 +02:00
la dernière ajoutée.
2024-04-23 13:25:28 +02:00
Cette façon de faire réduit les performances.
2024-04-21 11:57:37 +02:00
\subsection{Répartition par \ws}
2024-04-21 11:57:37 +02:00
\begin{description}
2024-04-25 02:13:56 +02:00
\item[\bone] \hspace{1em}
\begin{description}
\item[\mone] Le programme a été lancé \textbf{100 fois}.
Le temps moyen d'exécution a été de \textbf{0,229 secs}
\item[\mtwo] Le programme a été lancé \textbf{100 fois}.
Le temps moyen d'exécution a été de \textbf{0,308 secs}
\end{description}
\item[\btwo] \hspace{1em}
\begin{description}
\item[\mone] Le programme a été lancé \textbf{100 fois}.
Le temps moyen d'exécution a été de \textbf{0,447 secs}
\item[\mtwo] Le programme a été lancé \textbf{100 fois}.
Le temps moyen d'exécution a été de \textbf{1,131 secs}
\end{description}
2024-04-21 11:57:37 +02:00
\end{description}
2024-04-25 13:30:46 +02:00
Dans cette implémentation, nous n'utilisons plus une pile, mais un deque de tâches.
2024-04-23 13:25:28 +02:00
Cette façon de faire est légèrement meilleur que \docref{desc:th_pile}.
2024-04-25 13:18:47 +02:00
Dans la \autoref{fig:btm-ws}, nous observons que les \coeur{}s du CPU sont
2024-04-25 13:30:46 +02:00
proches de 100 \% d'utilisation. Comparé à \docref{stats:stack}, nous gagnons
en moyenne \approx~10 \% de l'utilisation du processeur dans son entièreté.
2024-04-25 02:43:13 +02:00
\begin{figure}[h!]
\centering
2024-04-25 02:53:29 +02:00
\includegraphics[alt={Graphique},width=\textwidth]{imgs/bottom-ws.jpg}
2024-04-25 02:43:13 +02:00
\caption{Exploitation des ressources sur la \mone~avec \docref{desc:ws}}
\label{fig:btm-ws}
2024-04-25 02:43:13 +02:00
\end{figure}
2024-04-25 17:07:48 +02:00
% TODO: Afficher les statistiques de vols (+ parler de la structure qui récupère
% ses données pour bien dire que on les récupère pas à la sauvage)
\section{Interprétation}
% TODO: Ici il faudrait interpréter les données/statistiques de la section
% du dessus
2024-04-25 02:43:13 +02:00
\clearpage
\appendix
\section{Crédits}
2024-04-25 02:43:13 +02:00
J'ai utilisé un bout de code de \href{https://expreg.org/amsi/C/}{Farès Belhadj}
d'un TP de L2 pour afficher une image au format \texttt{bmp} afin vérifier que
le \btwo~fonctionnait correctement. Ce qui donne la \autoref{fig:mandelbrot}.
2024-04-25 02:43:13 +02:00
\begin{figure}[h!]
\centering
2024-04-25 02:53:29 +02:00
\includegraphics[alt={Fractale mandelbrot},width=0.7\textwidth]{imgs/mandelbrot.jpg}
2024-04-25 02:43:13 +02:00
\caption{Example de Mandelbrot}
\label{fig:mandelbrot}
2024-04-25 02:43:13 +02:00
\end{figure}
\end{document}