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).

10 réponses

1 2 3
Avatar
lhabert
Tribulations Parallèles :

Question: comment peut-on écrire simplement une grosse structure C de 500Mo
(une structure avec des pointeurs de pointeurs, des choses comme ça) dans
un fichier?


Il n'y a pas de méthode simple. Je dirais de commencer par essayer de
simplifier la structure de ta structure : regrouper au maximum tes machins
dans des gros tableaux et utiliser des indices à l'intérieur de ces tableaux
en lieu et place de pointeurs. Comme ça, tu as des gros blocs que tu peux
lire/écrire quasiment tels quels. Il te reste encore à gérer les pointeurs
entre blocs, et là, il n'y a pas de recette miracle, il faut bricoler. En
plus de l'aide à la marshallisation, ça a des chances de diminuer la
consommation mémoire, et d'améliorer la localité des accès mémoires, et donc
de faire un meilleur emploi de la mémoire cache (il y a le même problème au
niveau mémoire cache/RAM que RAM/disque dur).

Existe-t-il des bibliothèques dédiées à ça?


Pas que je sache. Le C est de toutes manières de trop bas niveau pour se
prêter facilement à l'implémentation générique d'une telle bibliothèque.

En effet, je crois qu'il y a dans la bibliothèque standard C des fonctions
comme "tmpfile" qui ouvre un fichier en écriture binaire,


Non, ça sert juste à créer un fichier temporaire.

De plus, est-on sûr que le fichier sera contigu;


Non, c'est l'affaire de l'OS, qui fait ce qu'il veut mais qui est censé
faire son boulot pas trop mal quand il a suffisament de marche de manoeuvre
(si le disque est presque plein, évidemment, il va bien être forcé de
grapiller les secteurs un par un).

d'après ce que vous me dites, s'il est découpé en quelques morceaux, ce
n'est pas trop grave, mais s'il est découpé en 10000 morceaux, ça va être
embêtant.


Oui et non, en fait, ce qui importe, c'est que la taille des morceaux soit
au moins du même ordre de grandeur que la taille des blocs que tu lis d'un
coup.

Cela dépend du système de partitionnement, n'est-ce pas? Et en EXT3, je
crois qu'il n'y a pas ce genre de problèmes:


Oui.

Par ailleurs, je peux effectivement me débrouiller pour lire des données de
temps en temps, par paquet de 500 Mo (sur 100 Go au total), et travailler
dessus, directement dans la RAM, avant d'écrire le résultat sur le disque.


Alors tu peux sortir le champagne.

Avatar
Fabien LE LEZ
On Tue, 13 Jun 2006 23:53:12 +0200, Tribulations Parallèles
:

Étant donné que le domaine "freeee_._frspaM" n'existe pas, je
t'encourage vivement à rajouter ".invalid" à la fin. Merci d'avance.


Pourquoi?


D'une part, un serveur a parfaitement le droit de refuser ton message.
Le nom de domaine doit soit être valide, soit se terminer par
".invalid".

D'autre part, comme le ".invalid" est une convention, on détecte
beaucoup plus vite (et éventuellement automatiquement) que l'adresse
est bidon.

Je veux dire, je suis tout prêt à le changer (c'est pas très
élégant, c'est vrai), mais est-ce que ça pose un problème particulier? J'ai
peur qu'en rajoutant simplement .invalid les robots puissent détecter mon
adresse: c'est pour ça que j'ai pris quelque chose de très compliqué.


Je ne vois pas en quoi rajouter ".invalid" à la fin rendra la
détection plus facile.
Mais si tu as peur des spammeurs, je t'encourage vivement à utiliser
une vraie adresse bidon. On ne pourra pas plus (ni moins) te répondre,
et tu ne risqueras aucun spam.
Je te conseille "".



Question: comment peut-on écrire simplement une grosse structure C de 500Mo
(une structure avec des pointeurs de pointeurs, des choses comme ça) dans
un fichier? Existe-t-il des bibliothèques dédiées à ça?


Cherche "serialization" sur Google, et/ou demande sur fr.comp.lang.c.
Je ne connais rien à ce langage ; en C++, il y a plusieurs
bibliothèques, dont celle de Boost.

De plus, est-on sûr que le fichier sera contigu;


Ça dépend du bon vouloir de Linux.

Je suppose qu'il faut utiliser la fonction qui va bien pour lui
indiquer à l'avance la taille totale de ton fichier, et il se
démerdera, s'il y a assez de place sur le disque, pour éviter au
maximum la fragmentation.

Cela dépend du
système de partitionnement, n'est-ce pas?


Oui et non.

Si tu as une partition de 200 Go avec 100 Go de fichiers disséminés
ici ou là sur le disque, tu ne pourras pas y mettre un fichier de
100 Go en 1 seul bloc, car il n'y a aucun bloc de 100 Go libre.

Par ailleurs, je peux effectivement me débrouiller pour lire des données de
temps en temps, par paquet de 500 Mo (sur 100 Go au total)


Dans ce cas, tu créeras sans doute 200 fichiers de 500 Mo.


Avatar
lhabert
Tribulations Parallèles :

Finalement, non, je ne pense pas que ce soit une bonne idée d'essayer: Linux
risque de Swaper quand je ne le veux pas, alors qu'avec la connaissance de
mon algorithme, je peux traiter mes données par paquet dans la RAM, et
éviter toute lecture sur le disque pendant ce traitement (cf autre post de
ce thread).


Linux ne s'amuse pas à swapper pour le plaisir. Avec la connaissance de ton
algorithme, tu peux le programme de sorte qu'il n'accède pendant une longue
tranche de temps qu'à un bloc de 500Mo sur les 100Go de son espace mémoire
virtuel, et alors tu vas vite te retrouver avec cette tranche présente en
mémoire physique et tout le reste partit dans le swap, et à partir de là,
tout va rouler.

Et ça te facilite hallucinement la tache d'implémentation, de laisser l'OS
faire le boulot.

Avatar
lhabert
Fabien LE LEZ :

Je suppose qu'il faut utiliser la fonction qui va bien pour lui
indiquer à l'avance la taille totale de ton fichier,


Elle n'existe pas.

Avatar
Fabien LE LEZ
On Tue, 13 Jun 2006 23:56:35 +0200, Pascal Bourguignon
:

http://www.digitimes.com/news/a20050729PR208.html


"Sorry, the page you are trying to open is available only for our paid
subscribers."

Pas plus de $55786 pour une carte mère dual opteron avec 64 Go.


Je viens de regarder Windows Vista (bêta 2). Je pense qu'une machine
comme ça devrait être bien adaptée pour le faire tourner décemment.

Avatar
Nicolas George
Fabien LE LEZ wrote in message
:
C'est pas la taille du swap, c'est la quantité de mémoire adressable
par ton programme. Si un pointeur ne fait que 32 bits, tu ne peux pas
adresser plus de 2^32 octets.


Les processeurs 32 bits compatibles intel permettent d'adresser plus de 4 Go
en utilisant la segmentation : on charge dans un registre (16 bits) le
numéro d'un segment, qui peut faire jusqu'à 4 Go. Mais la politique sous
Linux est de ne pas utiliser cette fonctionnalité, et tout ceux qui ont déjà
programmé du DOS 16 bits se félicitent de ce que les processeurs 64 bits
débarquent avant que la quantité de mémoire physique commune ne dépasse la
limite des 32 bits.

À noter que le noyau se réserve une certaine portion de l'espace d'adressage
des processus, de sorte que seulement 3 Go au total sont effectivement
utilisables.

Avatar
Nicolas George
Luc Habert wrote in message <e6nd17$2h2l$:
Comme ça, tu as des gros blocs que tu peux
lire/écrire quasiment tels quels.


Attention, il faut absolument préciser que ce genre de méthode est valide
pour faire un fichier temporaire qui sera réutilisé ensuite par le même
programme dans le même environnement. Pour toute autre utilisation
(sauvegarde durable, transfert par réseau), il faut absolument convertir
manuellement les valeurs élémentaires en une représentation sous forme
d'octets en utilisant leurs propriétés arithmétiques.

Non, c'est l'affaire de l'OS, qui fait ce qu'il veut mais qui est censé
faire son boulot pas trop mal quand il a suffisament de marche de manoeuvre


Note que si c'est vraiment critique, on peut décider de faire les choses à
la main, en utilisant une partition directement, sans système de fichiers.
Certains serveurs de base de données procèdent ainsi pour les vraiment gros
systèmes. Je ne pense pas que le posteur original soit dans une situation où
c'est souhaitable, mais il fallait le préciser pour être exhaustif.

Soit dit en passant, je n'ai pas compris comment fonctionne le cache quand
aucun filesystem n'est monté.

Avatar
Nicolas George
Pascal Bourguignon wrote in message
:
Peut-être qu'une solution simple serait de compiler un user-mode-linux
64-bit même sur un processeur 32-bit?


Pas possible : UML virtualise uniquement les appels système, tout le reste
s'exécute nativement sur le processeur, donc on ne peut pas changer
d'architecture. Avec un qemu, ça doit être possible, mais ça risque de se
traîner quand même pas mal.

Avatar
Fabien LE LEZ
On Tue, 13 Jun 2006 23:03:50 +0000 (UTC), Nicolas George
<nicolas$:

et tout ceux qui ont déjà
programmé du DOS 16 bits se félicitent de ce que les processeurs 64 bits
débarquent avant que la quantité de mémoire physique commune ne dépasse la
limite des 32 bits.


Je confirme. Les ingénieurs d'Intel qui avaient pondu cette horreur
mériteraient d'être pendus. Et ceux qui ont imaginé la remettre au
goût du jour méritent encore pire.

Avatar
Tribulations Parallèles
Luc Habert wrote:

Linux ne s'amuse pas à swapper pour le plaisir. Avec la connaissance de
ton algorithme, tu peux le programme de sorte qu'il n'accède pendant une
longue tranche de temps qu'à un bloc de 500Mo sur les 100Go de son espace
mémoire virtuel, et alors tu vas vite te retrouver avec cette tranche
présente en mémoire physique et tout le reste partit dans le swap, et à
partir de là, tout va rouler.

Et ça te facilite hallucinement la tache d'implémentation, de laisser l'OS
faire le boulot.


Merci pour ta réponse.
Je ne suis pas sûr que cela soit la meilleure façon de faire.
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?
Dans ce cas, cela voudrait dire que je n'aurais pas à utiliser
mmap/msync/munmap, mais plutôt à stocker mes structures de données dans des
fichiers, et d'écrire et lire dedans. Comme dit dans un précédent post, là
j'aurais 200 fichiers de 500Mo. Je ne vois pas ce que pourrait m'apporter
mmap/mync/munmap ici.
Et alors, a priori même si mes fichiers ne sont pas contigus sur le disque,
cela ne devrait pas prendre un temps très grand. Comme suggéré par Rémi
Moyen, je pourrais utiliser deux threads: un qui lit ou écrit les résultats
des calculs, et un qui calcule pendant ce temps-là.

Cordialement,

Julien

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

1 2 3