pehache
2021-05-07 13:19:09 UTC
Bonjour,
J'ai récupéré un code de calcul universitaire, qui travaille
entièrement en mémoire, notamment avec 3 très gros tableaux. J'ai
besoin de le tester avec des paramètres qui vont de loin excéder la RAM
disponible sur les machines dont je dispose.
Si j'avais eu à écrire un tel code, j'aurais géré ça avec des
fichiers pour stocker temporairement certains résultats et décharger la
RAM. En effet, l'algo travaille relativement séquentiellement sur chaque
tableau, et on pourrait ne garder en RAM que les parties utiles... Mais
modifier en profondeur le code existant prendrait trop de temps (pas que
ce serait compliqué, mais beaucoup d'endroits sur lesquels intervenir,
dans un code pas commenté, avec des gros risques d'erreur car des indices
dans tous les sens, etc...).
Je me demandais donc si utiliser des (très gros) fichiers memory mapped,
sur lesquels on ferait pointer les (très gros) tableaux, serait une
solution. Ca permettrait en tous cas de ne pas toucher à toute la partie
algo.. Je ne connais pas vraiment, et en plus le C moins j'en fais mieux
je me porte habituellement...
J'ai fait quelques tests avec des petits exemples trouvés sur le web, et
je vois que les flag utilisés dans la commande mmap() ont vraiment une
grosse influence sur ce qu'on peut faire et les performances.
MAP_NORESERVE : je n'ai pas compris exactement ce qu'il faisait, mais sans
lui on ne peut apparemment pas mapper un volume plus grand que la taille
RAM+swap. J'en ai donc besoin à priori.
MAP_SHARED : ça m'a l'air d'être exactement comme si on écrivait/lisait
directement dans le fichier, avec le cache RAM usuel. Les perfs sont
moyennes.
MAP_PRIVATE : perfs meilleures, mais les écritures donnent visiblement
lieu à de l'allocation de RAM, qui n'est ensuite pas libérée. Donc une
fois qu'on a écrit le volume correspondant à la taille de la RAM dans le
tableau, ça swappe (et quand on atteint le volume RAM+swap ça coince).
Une solution semble être de démapper/remapper de temps en temps pour
forcer la RAM allouée à se vider dans le fichier et à se libérer.
L'option MAP_NORESERVE + MAP_PRIVATE me semble préférable pour mon cas,
mais il y a peut-être mieux à faire, et je n'ai peut-être pas tout
compris...
Des conseils ?
J'ai récupéré un code de calcul universitaire, qui travaille
entièrement en mémoire, notamment avec 3 très gros tableaux. J'ai
besoin de le tester avec des paramètres qui vont de loin excéder la RAM
disponible sur les machines dont je dispose.
Si j'avais eu à écrire un tel code, j'aurais géré ça avec des
fichiers pour stocker temporairement certains résultats et décharger la
RAM. En effet, l'algo travaille relativement séquentiellement sur chaque
tableau, et on pourrait ne garder en RAM que les parties utiles... Mais
modifier en profondeur le code existant prendrait trop de temps (pas que
ce serait compliqué, mais beaucoup d'endroits sur lesquels intervenir,
dans un code pas commenté, avec des gros risques d'erreur car des indices
dans tous les sens, etc...).
Je me demandais donc si utiliser des (très gros) fichiers memory mapped,
sur lesquels on ferait pointer les (très gros) tableaux, serait une
solution. Ca permettrait en tous cas de ne pas toucher à toute la partie
algo.. Je ne connais pas vraiment, et en plus le C moins j'en fais mieux
je me porte habituellement...
J'ai fait quelques tests avec des petits exemples trouvés sur le web, et
je vois que les flag utilisés dans la commande mmap() ont vraiment une
grosse influence sur ce qu'on peut faire et les performances.
MAP_NORESERVE : je n'ai pas compris exactement ce qu'il faisait, mais sans
lui on ne peut apparemment pas mapper un volume plus grand que la taille
RAM+swap. J'en ai donc besoin à priori.
MAP_SHARED : ça m'a l'air d'être exactement comme si on écrivait/lisait
directement dans le fichier, avec le cache RAM usuel. Les perfs sont
moyennes.
MAP_PRIVATE : perfs meilleures, mais les écritures donnent visiblement
lieu à de l'allocation de RAM, qui n'est ensuite pas libérée. Donc une
fois qu'on a écrit le volume correspondant à la taille de la RAM dans le
tableau, ça swappe (et quand on atteint le volume RAM+swap ça coince).
Une solution semble être de démapper/remapper de temps en temps pour
forcer la RAM allouée à se vider dans le fichier et à se libérer.
L'option MAP_NORESERVE + MAP_PRIVATE me semble préférable pour mon cas,
mais il y a peut-être mieux à faire, et je n'ai peut-être pas tout
compris...
Des conseils ?