Add NUMA, ^2, LCC
This commit is contained in:
parent
2f7790f2bc
commit
2fc97b6285
BIN
figs/lstopo.pdf
Normal file
BIN
figs/lstopo.pdf
Normal file
Binary file not shown.
135
main.tex
135
main.tex
@ -20,8 +20,8 @@
|
||||
|
||||
% titre
|
||||
\title{Caractérisation de l’instruction \texttt{clflush} sur systèmes multi-\ang{socket}}
|
||||
\author{\textsc{Augustin LUCAS}\\ENS de Lyon\\ \\Encadré par :\\
|
||||
\textsc{Guillaume DIDIER}, \textsc{Angeliki KRITIKAKOU}\\
|
||||
\author{Augustin \textsc{Lucas}\\ENS de Lyon\\ \\Encadré par :\\
|
||||
Guillaume \textsc{Didier}, Angeliki \textsc{Kritikakou}\\
|
||||
Équipe \textsc{Taran}\\
|
||||
Laboratoire \textsc{Irisa}\\
|
||||
Université de \textsc{Rennes} 1}
|
||||
@ -46,24 +46,35 @@ Université de \textsc{Rennes} 1}
|
||||
|
||||
\section{Introduction}
|
||||
|
||||
\TODO{
|
||||
Points à aborder
|
||||
\begin{itemize}
|
||||
\item NUMA balancing
|
||||
\item Low Core Count, possibilité cores fantôme
|
||||
\item Pourquoi nombre de coeurs = puissance de 2 ?
|
||||
\end{itemize}
|
||||
}
|
||||
\TODO{Réordonner, faire des liens entre les subsubsections}
|
||||
|
||||
\subsubsection{Low Core Count}
|
||||
|
||||
Pour répondre à des demandes variées, \ang{Intel} base ses processeurs serveurs sur
|
||||
trois tailles \TODO{à partir de la micro-architecture Haswell ?}:
|
||||
\begin{itemize}
|
||||
\item LCC (\ang{Low Core Count}) : de 4 à 8 coeurs physiques pour
|
||||
la micro-architecture Haswell (jusqu'à 10 pour Broadwell)
|
||||
\item MCC (\ang{Medium Core Count}) : de 10 à 12 coeurs pour Haswell (12 à 14 pour Broadwell)
|
||||
\item HCC (\ang{High Core Count}) : de 14 à 18 coeurs pour Haswell (16 à 24 pour Broadwell)
|
||||
\end{itemize}
|
||||
|
||||
Les machines que nous utiliserons sont uniquement basées sur la \ang{die} LCC, mais certaines
|
||||
(les Broadwell à 8 coeurs par exemple) sont alors livrées avec des coeurs désactivés. La \ang{slice}
|
||||
de cache L3 associée est alors désactivée également. Cela pose tout de même question sur la possibilité
|
||||
de sauts supplémentaires dûs à ces coeurs manquants. \TODO{Alors, quel est le coeur désactivé ?
|
||||
Est-ce similaire sur toutes les puces du même modèle ou choisi spécifiquement en usine ? Quelle
|
||||
est la conséquence dans ce cas ?}
|
||||
|
||||
\subsection{Hiérarchie de cache}
|
||||
|
||||
La mémoire DRAM d'un ordinateur est lente comparée à la fréquence du CPU. Le CPU dispose donc de caches,
|
||||
basés sur une mémoire SRAM, plus petite mais plus rapide. Stocker en cache les éléments accédés
|
||||
basés sur des mémoires SRAM, plus petites mais plus rapides. Stocker en cache les éléments accédés
|
||||
le plus fréquemment permet donc de réduire le nombre d'appels à la mémoire et donc le temps d'exécution.
|
||||
|
||||
Les processeurs que nous étudions disposent de 3 niveaux de cache : L1, L2, L3.
|
||||
Chaque coeur possède, au premier niveau, un L1i (cache des instructions) et
|
||||
un L1d (cache des données). Au second niveau, il possède un L2 qui contient potentiellement
|
||||
Chaque coeur possède, au premier niveau, un L1-I (cache des instructions) et
|
||||
un L1-D (cache des données). Au second niveau, il possède un L2 qui contient potentiellement
|
||||
des données et des instructions. Au dernier niveau, le L3 est partagé entre tous les coeurs de la
|
||||
\ang{socket}, et celui-ci est inclusif de tous les caches de niveau inférieur : toute ligne
|
||||
stockée dans le cache L1 ou L2 est également dans le L3.
|
||||
@ -75,7 +86,7 @@ mais est réparti en différentes \ang{slices} : des tranches de mémoire accol
|
||||
\begin{figure}[ht]
|
||||
\centering
|
||||
\includegraphics[width=0.4\textwidth]{broadwell-die-shot}
|
||||
\caption{Broadwell Deca-Core die shot by Intel - annotated by Wikichip~\cite{broadwelldieshot}}
|
||||
\caption{Broadwell Deca-Core die shot by Intel - annotated by Wikichip~\cite{broadwell-wikichip}}
|
||||
% L'espace vide l'est bien sur le die-shot, donc sûrement "Intel being stupid"
|
||||
\end{figure}
|
||||
|
||||
@ -85,6 +96,34 @@ la ligne y est chargée également. Une fonction de hachage non-documentée attr
|
||||
physique une unique \ang{slice} dans laquelle elle peut être mise en cache.
|
||||
Différents travaux~\cite{slice-reverse, practicalTiming} ont permis de déterminer cette fonction.
|
||||
|
||||
\label{poweroftwo} Si les fonctions initialement utilisées
|
||||
étaient simplement basés sur certains bits de l'adresse,
|
||||
la fonction de hachage utilisée à partir de la micro-architecture Sandy Bridge
|
||||
(et au moins jusqu'à Tiger Lake) utilise le XOR de plusieurs bits de chaque adresse physique
|
||||
pour générer chaque bit du numéro de \ang{slice}. Alors, la fonction de hachage est linéaire sur les
|
||||
processeurs avec un nombre de coeurs qui est une puissance de 2, mais une composante non-linéaire
|
||||
s'ajoute sur les autres processeurs.
|
||||
|
||||
\subsubsection{\ang{NUMA}}
|
||||
|
||||
\begin{figure}[ht]
|
||||
\centering
|
||||
\includegraphics[width=1.0\textwidth]{lstopo}
|
||||
\caption{Topologie \ang{NUMA} de \textit{paravance} extraite
|
||||
avec l'outil \texttt{lstopo} de \texttt{hwloc}}
|
||||
\end{figure}
|
||||
|
||||
Dans un système à plusieurs \ang{sockets}, chaque \ang{socket} a de la mémoire DRAM à laquelle il
|
||||
peut accéder directement. Sur les machines Intel, le \ang{QPI} (\ang{QuickPath Interconnect})
|
||||
permet à un processeur d'accéder au données localisées dans la mémoire rattachée à un autre processeur.
|
||||
|
||||
Le principe \ang{NUMA} (\ang{Non-uniform memory access}) délimite alors des groupes contenant
|
||||
un processeur et les adresses mémoire qui en sont rapprochées et les transmet au système d'exploitation.
|
||||
Cela permet à ce dernier d'allouer la mémoire dans les adresses proche du processeurs qui en a besoin.
|
||||
|
||||
Sur Linux, si beaucoup d'accès mémoire sont réalisés d'un processeur
|
||||
à des adresses qui lui sont éloignées, les pages correspondantes sont migrées.
|
||||
|
||||
\subsection{Protocoles de cohérence de cache}
|
||||
|
||||
Dans des systèmes à plusieurs coeurs, d'autant plus avec plusieurs processeurs, où chaque coeur a
|
||||
@ -121,11 +160,6 @@ même \ang{socket}, mais par \ang{snooping} entre les deux \ang{sockets}.
|
||||
|
||||
\subsubsection{Mémoire partagée}
|
||||
|
||||
\TODO{était bien formulé dans le 2.2 de~\cite{flushflush}
|
||||
donc reprend largement les mêmes idées, ce n'est pas une citation et ces infos
|
||||
ne sont pas non plus particulières à ce papier.
|
||||
Comment dire que ça en est inspiré, faut-il le faire ?}
|
||||
|
||||
Les systèmes d'exploitation utilisent le principe de mémoire partagée pour
|
||||
réduire l'utilisation totale de mémoire physique. C'est-à-dire que différentes
|
||||
pages de mémoire virtuelle correspondent à une même page de mémoire physique,
|
||||
@ -141,8 +175,8 @@ les différentes instances du programme.
|
||||
|
||||
Une autre forme de déduplication consiste à regarder
|
||||
les pages de mémoire contenant les mêmes données et à les combiner.
|
||||
Cela peut amener différents processus \TODO{\ang{sandbox}és}
|
||||
ou même de machines virtuelles différentes à partager des données en commun.
|
||||
Cela peut amener différents processus \ang{sandbox}és
|
||||
même de machines virtuelles différentes à partager des données en commun.
|
||||
|
||||
\subsubsection{L'instruction \texttt{clflush}}
|
||||
|
||||
@ -246,10 +280,24 @@ messages échangés en fonction de l'état de cohérence des lignes
|
||||
évincées du cache. Cela passe par l'étude des sources de variabilité et permet de
|
||||
mieux choisir un seuil propre à chaque combinaison attaquant/victime/\ang{slice}.
|
||||
|
||||
Ce travail s'était intéressé à certains processeurs Intel de micro-architectures \ang{Coffee Lake} et
|
||||
Ce travail s'était intéressé à certains processeurs Intel de micro-architectures
|
||||
\ang{Coffee Lake} et
|
||||
\ang{Haswell} à une seule \ang{socket}, mais a révélé que les résultats seraient bien plus complexes
|
||||
sur des systèmes à plusieurs \ang{sockets}.
|
||||
|
||||
\TODO{paragraphe à déplacer}
|
||||
\label{nonprivilegedinfo} Dans un scénario réel,
|
||||
l'attaquant peut choisir le coeur sur lequel il s'exécute,
|
||||
a accès au coeur sur lequel le processus victime s'exécute via \texttt{/proc/pid}.
|
||||
La \ang{slice} peut-être trouvée en utilisant l'adresse physique mais cette information demande
|
||||
généralement des privilèges qu'un attaquant n'aura pas. En revanche, si la fonction de hachage
|
||||
est linéaire -- ce qui est le cas si le nombre de coeurs
|
||||
est une puissance de 2 (\ref{poweroftwo}) --
|
||||
il est possible de définir une classe d'équivalence des adresses des pages qui appartiennent aux
|
||||
mêmes \ang{slices}. Une connaissance fine d'éléments dépendants du numéro de \ang{slice} -- comme
|
||||
le temps d'exécution de \texttt{clflush} dans certaines conditions -- permettrait alors
|
||||
de déterminer la \ang{slice}.
|
||||
|
||||
\section{Organisation des expériences}
|
||||
|
||||
Les expériences ont été faites sur 6 machines différentes,
|
||||
@ -258,8 +306,7 @@ par processeur répondant aux critères suivants:
|
||||
\begin{itemize}
|
||||
\item Processeur Intel ;
|
||||
\item Exactement 2 \ang{socket} ;
|
||||
\item Nombre de coeurs par \ang{socket} est une puissance de
|
||||
deux \footnote{\TODO{l'expliquer en amont et le rappeler ici, voir Intro}} ;
|
||||
\item Nombre de coeurs par \ang{socket} est une puissance de deux
|
||||
\item Micro-architecture antérieure à SkyLake\footnote{Le L3 n'est plus inclusif
|
||||
sur les processeurs serveur à partir de SkyLake et la topologie devient plus complexe}
|
||||
\end{itemize}
|
||||
@ -281,12 +328,29 @@ Les machines suivantes ont donc été utilisées~\cite{g5k-nodes}
|
||||
\end{tabular}
|
||||
\end{center}
|
||||
|
||||
Le turbo a été désactivé sur toutes les machines.
|
||||
La fréquence des coeurs fixée : à la fréquence minimale supportée par les processeurs ;
|
||||
le mode performance ne donnant pas le même résultat que sur les machines \ang{Intel Core}.
|
||||
Le \ang{NUMA balancing} a également été désactivé (à l'échelle du système),
|
||||
ce qui peut se faire pour le processus courant sans
|
||||
privilèges\footnote{\TODO{à vérifier ! voir les "À faire"}}.
|
||||
La prise de mesure consistait à relever pour un lot d'adresse (chacune correspondant à une \ang{slice})
|
||||
les temps d'exécution de l'instruction \texttt{clflush} pour toutes les paires de coeurs
|
||||
et tous les états de cohérence possibles.
|
||||
|
||||
Initialement, le turbo était désactivé sur toutes les machines, la fréquence des coeurs était fixée
|
||||
à la fréquence maximale en activant le mode "performance" via \texttt{cpufreq}.
|
||||
|
||||
Nous avons trouvé que:
|
||||
\begin{itemize}
|
||||
\item Contrairement aux machine \ang{Intel Core}, le mode performance ne permet pas
|
||||
de fixer la fréquence de tous les coeurs à la fréquence maximale possible.
|
||||
Nous avons donc fixé la fréquence des coeurs à la fréquence minimale (généralement 400MHz) ;
|
||||
\item L'architecture \ang{NUMA} impliquant de déplacer les pages exploitées principalement par un
|
||||
processeur distant, les adresses physiques changeaient durant l'expérience, ce qui rendait
|
||||
tous les résultats complètement incohérents.
|
||||
Nous avons donc désactivé le \ang{NUMA balancing} via \texttt{numactl},
|
||||
ce qui peut se faire pour le processus courant sans privilèges\footnote{
|
||||
Il faudrait vérifier que cela fonctionne aussi pour les pages
|
||||
partagées comme les bibliothèques
|
||||
}.
|
||||
\item Nous avons également fixé la fréquence de l'\ang{uncore} via un MSR, mais cela n'a
|
||||
pas eu de grand impact sur la clarté des résultats.
|
||||
\end{itemize}
|
||||
|
||||
Les fichiers de résultats bruts sont accessibles en ligne~\cite{g5k-results}.
|
||||
|
||||
@ -332,17 +396,12 @@ c'est la numérotation que nous utiliserons pour la suite:
|
||||
|
||||
Pour trouver la numérotation des \ang{slices}, deux méthodes sont possibles:
|
||||
\begin{itemize}
|
||||
\item Utiliser la méthode proposée pour un attaquant non-privilégié (\ref{nonprivilegedinfo}).
|
||||
Cela nécessite une connaissance préalable de la topologie ;
|
||||
\item Utiliser les compteurs de performance pour déterminer la \ang{slice} d'une adresse.
|
||||
Cela nécessite
|
||||
de lire les MSR correspondants donc d'avoir un accès \ang{root}. Nous avons suivi cette méthode
|
||||
afin d'être sûr que les numéros de \ang{slice} correspondent aux numéros de coeurs ;
|
||||
\item Utiliser la fonction de hachage~\cite{slice-reverse} pour
|
||||
déterminer la \ang{slice} de chaque adresse. Comme la fonction est appliquée sur
|
||||
l'adresse virtuelle et non pas physique, celle-ci est déterminée à permutation
|
||||
près.\footnote{\TODO{référence à l'explication du nb de coeur = puissance de 2 en intro}}
|
||||
Il serait envisageable de donner une méthode permettant de
|
||||
réordonner automatiquement les \ang{slices}, et donc de déterminer l'information de la slice
|
||||
depuis un utilisateur non privilégié.
|
||||
afin d'être sûr que les numéros de \ang{slice} correspondent aux numéros de coeurs.
|
||||
\end{itemize}
|
||||
|
||||
|
||||
|
2
refs.bib
2
refs.bib
@ -32,7 +32,7 @@
|
||||
HAL_VERSION = {v1},
|
||||
}
|
||||
|
||||
@misc{broadwelldieshot,
|
||||
@misc{broadwell-wikichip,
|
||||
title={Broadwell - Microarchitectures - Intel - WikiChip (2024)},
|
||||
url={https://en.wikichip.org/wiki/intel/microarchitectures/broadwell_(client)#Deca-core_Broadwell},
|
||||
note={\url{https://en.wikichip.org/wiki/intel/microarchitectures/broadwell_(client)#Deca-core_Broadwell}},
|
||||
|
Loading…
Reference in New Issue
Block a user