OVH Cloud OVH Cloud

remplacement de la RAM par du disque dur: variation du temps d'accès

24 réponses
Avatar
Tribulations Parallèles
Bonjour à tous,

J'ai codé un programme qui réalise des calculs qui demandent beaucoup de RAM
(environ 500 Mo).
Je compte améliorer le programme, mais alors j'ai besoin de 100 Go de RAM
(oui!). Ce n'est pas possible. J'envisage donc de stocker mes données sur
le disque dur; plusieurs question en découlent:

1- Comment va évoluer le temps de lecture ou écriture des données? En
cherchant, je vois que le temps d'accès à la RAM est de l'ordre de 10 nano
seconde, au disque dur de 10 milli seconde. Un facteur un million se
dessine donc: il est trop important. Pour mon application, je peux tolérer
un facteur 10000. Or, quand je fais hdparm -t /dev/hda sur mon ordi, il me
donne 22 MB/sec: cela représente une lecture bien plus rapide que 10 milli
seconde pour accéder à chaque bit; pourquoi? A quoi correspondent ces
temps? Où trouver de la doc didactique sur le fonctionnement du disque dur?
Par exemple, si j'essaie de copier un fichier de quelques centaines de Mo
sur mon disque ($ cp foo.avi bar.avi), cela prend plusieurs dizaines de
secondes; mais là il lit et écrit; comment cela évolue-t-il si je ne fais
que charger le contenu d'un gros fichier dans la RAM? Bref, je suis
dépassé, et j'ai du mal à trouver de la doc sérieuse sur internet (mais
sûrement que je cherche mal).

2- Pour stocker ces données dans des fichiers, avez-vous une expérience à
faire partager? Existe-t-il des bibliothèques spéciales sous Linux? A
priori aucun intérêt à compresser les données?

Bref je suis preneur de tout conseil.

Merci d'avance,

Julien
--
"Allez, Monsieur, allez, et la foi vous viendra." (D'Alembert).

4 réponses

1 2 3
Avatar
Nicolas George
Tribulations Parallèles wrote in message
<4490442d$0$10291$:
En effet, voici de manière imagée ce que j'ai à réaliser: je dispose de n
(ex: 200) tableaux T de taille m (ces m tableaux correspondant chacun à une
taille de 500 Mo), et je fais des opération compliquées sur p éléments de
chacun des tableau T de taille m: je commence pas les p premiers éléments:
1..p, puis 2..p+1, puis ainsi de suite jusqu'aux éléments m-p+1..m
Donc si je commence à traiter par exemple le tableau n, qui est
complètement sur le swap, et que je fais une opération sur les p premiers
éléments (ex: moyenne arithmétique), l'OS va aller les chercher sur le
disque, et les mettre en RAM (éventuellement virer quelque chose qui y
était déjà). Mais quand je vais traiter les éléments 2..p+1, il va devoir
aller chercher T[p+1] sur le swap, et ainsi de suite. Si m très grand
devant p, cela va faire un paquet d'accès disque. Alors que si je libère la
mémoire allouée jusqu'à présent, et que je charge en mémoire l'intégralité
du tableau m de 500 Mo, je vais pouvoir réaliser l'opération sur le tableau
sans un seul accès disque: donc ça va être plus rapide.
Es-tu d'accord avec ce que je dis?


Non, ça ne va pas se passer comme ça. Ce qui va se passer, c'est que quand
tu vas lire pour la première fois les éléments 0 à p, le noyau va se dire
que tu vas probablement bientôt avoir besoin de l'élément p+1, donc il va
initier son chargement en mémoire, de manière asynchrone, pendant que tu
reprends la lecture des éléments 2 à p, ce qui fait que quand tu en arrives
à l'élément p+1, il est déjà en mémoire, et tu n'as perdu absolument aucun
temps.

Au contraire, si tu fais manuellement le chargement-déchargement, ton
processus es bloqué pendant les opérations disque, alors qu'il aurait pu
passer le temps à faire du calcul utile, donc tu perds du temps. D'autre
part, le noyau sait mieux que toi quelle quantité de mémoire est
effectivement disponible, et il fera donc des décisions plus éclairées,
comme garder en mémoire un exemplaire et demie de ton tableau plutôt que
seulement un, ou même dégager openoffice pour en faire tenir deux.

D'une manière générale, quand tu es confronté à ce genre de situation, la
règle d'or est : profile, don't speculaite : tu ne passes pas des heures à
te demander si machin va te faire gagner quelques pouillèmes de seconde par
rapport à truc alors que ce sont des quantités très difficilement
quantifiables ; au contraire, tu écris ton programme au plus simple (donc
ici, machine 64 bits et mmap ou malloc de l'ensemble des données, et laisser
le noyau se débrouiller avec la MMU), et tu examines a posteriori si le
résultat est trop lent.

Si c'est effectivement trop lent, il y a des moyens simples de conseiller le
noyau pour la meilleure stratégie. Sous Linux, en particulier, il y a
l'appel système madvise qui sert précisément à ça. Mais re répète, il ne
faut commencer à faire des bidouilles avec madvise.que si les performances
de la version naïve sont mauvaises.

Avatar
Tribulations Parallèles
Nicolas George wrote:

Non, ça ne va pas se passer comme ça. Ce qui va se passer, c'est que quand
tu vas lire pour la première fois les éléments 0 à p, le noyau va se dire
que tu vas probablement bientôt avoir besoin de l'élément p+1, donc il va
initier son chargement en mémoire, de manière asynchrone, pendant que tu
reprends la lecture des éléments 2 à p, ce qui fait que quand tu en
arrives à l'élément p+1, il est déjà en mémoire, et tu n'as perdu
absolument aucun temps.


Est-ce le "prefetch" évoqué à la fin de:

http://en.wikipedia.org/wiki/Virtual_memory

ou est-ce encore autre chose?

"Recently, some experimental improvements to the 2.6 Linux kernel have been
made by Con Kolivas, published in his fairly popular CK patchset. The
improvements, called "Swap Prefetch", employ a mechanism of pre-fetching
previously swapped pages back to physical memory even before they are
actually needed, as long as the system is relatively idle (so not to impair
performance) and there is available physical memory to use. This gives
several orders of magnitude faster access to the affected pages when their
owning process needs access to them, since they are effectively not swapped
out by then."

Julien

--
"Allez, Monsieur, allez, et la foi vous viendra." (D'Alembert).

Avatar
Nicolas George
Tribulations Parallèles wrote in message
<44907478$0$27366$:
Est-ce le "prefetch" évoqué à la fin de:

http://en.wikipedia.org/wiki/Virtual_memory

ou est-ce encore autre chose?


Pas exactement, je pense, mais c'en est proche. Mais je le répète : ne
commence à te poser ces questions que si tu constates un manque de
performances à ce niveau.

Avatar
Laurent
Pourquoi la taille du swap est limitée en 32 bits à 4 Go, et pas en 64
bits?


Tout bêtement parce que c'est la taille maximale adressable par un
registre de 32 bits : 2^32 = 4294967296 = 4Go

Il y a aussi une limite en 64 bits, mais nettement plus "confortable" :
2^64 = 18446744073709551616 = beaucoup de gigas ;)

1 2 3