IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Fonction malloc: allocation mémoire depuis le disque dur


Sujet :

C++

  1. #1
    Membre habitué Avatar de Rodrigue
    Inscrit en
    Août 2002
    Messages
    487
    Détails du profil
    Informations forums :
    Inscription : Août 2002
    Messages : 487
    Points : 157
    Points
    157
    Par défaut Fonction malloc: allocation mémoire depuis le disque dur
    Bonjour,

    A votre avis est-ce possible de faire une sorte de fonction malloc qui m'allouerait des blocs de mémoire dans un fichier sur mon disque dur?
    Il faudrait que je remplace ce bout de code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    template <class T>
    //...
    void* p = malloc( n * sizeof(T) );
       if( p == NULL )
          throw std::bad_alloc();
    return (T*)p;
    Je renvoie un pointeur de type void* que je caste en T* (l'appel au constructeur de la classe T est fait dans une autre fonction, ici il s'agit juste d'allouer la mémoire). Je vois mal comment renvoyer un pointeur de type void* depuis un fichier!?
    Quelqu'un pourrait-il m'expliquer, svp?

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Tu veux dire, un File Mapping ?
    Rien de standard : C'est de la programmation système, avec CreateFileMapping() sous Windows, mmap() sous unixoïde.

  3. #3
    Membre habitué Avatar de Rodrigue
    Inscrit en
    Août 2002
    Messages
    487
    Détails du profil
    Informations forums :
    Inscription : Août 2002
    Messages : 487
    Points : 157
    Points
    157
    Par défaut
    Oui mais lorsque je fais du filemapping, je dois mappé des parties (blocs) de fichiers en mémoire. Je dois gérer beaucoup de mémoire. Est-ce que je ne vais pas être limitée à la taille de la heap? Parce que j'ai déjà essayé avec ::HeapAlloc mais sans susscès:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     assert( mHeap != NULL );
            DWORD nBytes = n * sizeof(T);
     
    		std::cout << "allocate " << nBytes << " bytes\n";
     
            VOID* p = ::HeapAlloc( mHeap, 0, nBytes );
            if( p == NULL )
                throw std::bad_alloc();
            return pointer(p);
    Je suis limité à 198Mo d'allocation maximum (1Go de Ram sur le portable).

    Ce que je souhaiterais faire:
    - allouer des blocs de mémoire depuis un disque dur
    - pouvoir les unmapper lorsque j'ai besoin d'en mapper d'autres
    mais lorsque j'utilise un pointeur qui a été déréférencé être capable de remapper le bloc de fichier en mémoire.
    J'ai déjà commencé à écrire une classe pointeur pour cela mais elle est templatée ce qui pose problème quand je l'utilise dans les containers de la STL (c'est pour un allocateur de mémoire STL). Il peste car il n'aime pas que les pointeurs que je lui renvoie soit templatée, ce qui est logique...

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    J'ignore si les File Mappings sont limités ou non à la taille du Heap. Pour moi, c'est comme VirtualAlloc() : Ça ne devrait pas être vraiment limité...

  5. #5
    Membre habitué Avatar de Rodrigue
    Inscrit en
    Août 2002
    Messages
    487
    Détails du profil
    Informations forums :
    Inscription : Août 2002
    Messages : 487
    Points : 157
    Points
    157
    Par défaut
    Je viens d'essayer et ça l'est... En fonction du nombre de programmes que j'ai lancé en même temps que ma "simulation", j'ai un une exception générée lors d'une de mes allocations vers 58Mo à 192Mo...
    Note: HeapAlloc, utilise VirtualAlloc quand il alloue d'importants morceaux de mémoire...

    Sinon j'ai trouvé AWE mais il faut une machine surpuissantes ... style 16Go de RAM et en plus un processeur 64 bits

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Ces autres applications sont-elles donc assez nombreuses pour bouffer le restant du giga de RAM ?
    Car en théorie, VirtualAlloc() n'est limité que par la mémoire virtuelle disponible.

    Donc, si d'autres programment bouffent 800Mo + La taille du fichier de pagination, il est normal que VirtualAlloc() échoue...

    Au début, je croyais que tu parlais d'un programme tournant tout seul sur la machine...

  7. #7
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625

  8. #8
    Membre habitué Avatar de Rodrigue
    Inscrit en
    Août 2002
    Messages
    487
    Détails du profil
    Informations forums :
    Inscription : Août 2002
    Messages : 487
    Points : 157
    Points
    157
    Par défaut
    Oui je connais stxxl. Je l'utilise déjà d'ailleurs. Le problème est qu'il ne gère pas tous les containers de la STL. C'est pourquoi j'essaye d'écrire un std::allocator sur disque dur

  9. #9
    Expert éminent

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Points : 7 618
    Points
    7 618
    Billets dans le blog
    3
    Par défaut
    Hmmmm,

    J'avoues avoir du mal à comprendre le but ultime...

    Pour ce qui est du file-mapping, si je me souviens bien, ca ne foire que si la 'view' créée sur le mapping excede la mémoire disponible... Ce qui veut dire qu'on peut mapper le fichier entièrement, mais on ne voit qu'une fenêtre.

    Si le but est de sérialiser des données, alors effectivement, le file-mapping est une solution (bien plus rapide que l'utilisation des fichiers sequentiels), par contre la taille du mapping dépend du système (multiple d'une valeur définie dans la système), et surtout une mapping-view doit pouvoir tenir entièrement en mémoire (voir ci-dessous).

    Mais il faut bien garder à l'esprit que c'est une vue en mémoire d'un fichier, et j'ai bien l'impression que tu veux faire l'inverse: une sauvegarde en fichier de mémoire. Et ça, ca s'appelle de la mémoire virtuelle
    Il existe un tas de librairies pour ça, mais on en revient au même: toute la mémoire n'est pas visible en une fois, il faut utiliser des pages (ou des fenêtres).

    D'ou le VirtualAlloc...
    Par contre, sous x86, la taille allouable à un process par VirtualAlloc est limité à 2Go ! (voire 3Go si 4GT RAM Tuning). Impossible pour un process d'allouer plus, quelque soit la fonction utilisée (de toute façon, avec les pointeurs 32bits....). A part bien entendu sous Windows Server, et sous reserve que la mémoire virtuelle (systeme) soit disponible en quantité suffisante.

  10. #10
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Le problème est qu'il ne gère pas tous les containers de la STL.
    Oui enfin bien évidemment, je vois mal comment tu veux gérer des list...
    Il gère vector, map et peut-être set.
    Je vois pas trop ce que tu voudrais avoir d'autre.

  11. #11
    Membre habitué Avatar de Rodrigue
    Inscrit en
    Août 2002
    Messages
    487
    Détails du profil
    Informations forums :
    Inscription : Août 2002
    Messages : 487
    Points : 157
    Points
    157
    Par défaut
    Merci pour vos réponses, je sais déjà comment fonctionne le filemapping. J'ai créé une classe de gestion de mémoire virtuelle: un fichier est mappé en mémoire (enfin un bloc de la taille de la granularité du système), je peux écrire à n'importe quelle position dans le fichier (la taille de celui-ci augmente automatiquement s'il n'est pas assez long), le bon "bloc" est mappé automatiquement. Ca fonctionne pas trop mal, il vaut mieux jouer avec des accès séquentiels, si on ne veut pas voir les performances dégringoler (sinon on va avoir une floppée de unmap/mapviewfile). Ce n'est pas compatible avec la STL, je ne sais pas l'utiliser dans mon std::allocator... vu que les pointeurs renvoyés proviennent d'un espace mémoire qui peut être mappé ou démappé...

    C'est pour cela que j'avais eu l'idée de faire une classe "simulant" des pointeurs (un peu dans le même genre que autoptr ou Poco::sharedptr). Ce type de pointeur qui stockerait la position à laquelle se trouve la donnée qu'il référence dans un fichier. Je ne parle même pas de mémoire mappée ici, juste une abstraction de FILE* ou de std::ifstream...
    De plus, cet objet pointeur devrait être compatible avec les composants de la STL... J'ai commencé à écrire la classe (basée sur Poco::SharedPtr) mais je n'ai malheureusement pas encore eu le temps de la tester.
    Voilà, si d'autres personnes veulent se joindre à mon petit projet (juste un proof-of-concept), ils sont les bienvenus.

  12. #12
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Il n'est pas vraiment possible de faire des allocateurs de ce type, simplement parce que le standard impose que le reference_type soit T&.

    Ensuite, dans le cas de la STL, les implémentations ont le droit de supposer de nombreuses choses, en particulier que pointer_type est T* et que tous les allocateurs avec un même type sont équivalents.
    Ce qui rend d'ailleurs leur utilisation impossible avec des allocateurs de mémoire partagée par exemple.

  13. #13
    Membre habitué Avatar de Rodrigue
    Inscrit en
    Août 2002
    Messages
    487
    Détails du profil
    Informations forums :
    Inscription : Août 2002
    Messages : 487
    Points : 157
    Points
    157
    Par défaut
    Ce qui rend d'ailleurs leur utilisation impossible avec des allocateurs de mémoire partagée par exemple.
    Tu veux dire comme dans les listes: on alloue des noeuds et le type stocké (rebind<u>)?

    Je pense que tu as p-e raison mais je demande s'il n'y a pas quand même pas un moyen. Ce qui ne va pas aux allocateurs de la STL, c'est, je pense, qu'on utilise des templates. Y-a-t'il moyen de s'en passer? Je pense que oui, notamment en retournant des types void* et en les castant par après dans le std::allocator! Le type de la template ne sert, si je ne me trompe pas, que lors de l'incrémentation du pointeur, on pourrait lui passer un sizeof par une fonction pour l'initialiser, pourquoi pas? Lors d'un rebind, on pourrait encore passer par cette fonction pour mettre à jour la valeur de l'incrémentation. Ce qu'il faut c'est une sorte de fonction malloc mais qui alloue de la mémoire sur le disque dur.

    En fait la limitation, c'est la gestion de mémoire de windows! Je vais p-e me tourner du côté de linux...

  14. #14
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Quelle limitation?
    Si tu veux plus de mémoire virtuelle (jusqu'à 2/3Go en 32 bits), augmente simplement sa taille dans les paramètres système, non?

    Par contre, j'ignore si Windows 32 bits sait gérer plus de 2/3go AU TOTAL. Et je ne sais pas non plus pour Linux, en fait...

  15. #15
    Membre habitué Avatar de Rodrigue
    Inscrit en
    Août 2002
    Messages
    487
    Détails du profil
    Informations forums :
    Inscription : Août 2002
    Messages : 487
    Points : 157
    Points
    157
    Par défaut
    Non windows XP n'est pas capable de gérer plus de 3Go (pour cela il faut activer un flag). Il y a bien un mode AWE mais il n'est disponible que sous windows server 2003. De plus il faut un processeur itanium 64 bits (de mémoire). Enfin, il faut de la RAM en conséquence: ~16Go !
    La limitation dont je parle c'est le swap. On devrait pouvoir allouer autant de mémoire que l'on en a de disponible sur le système (RAM + HD libre); même si cela dégrade fortement les performances. Cela suppose déjà que les pointeurs soient en 64 bits. Sous linux, tout est reprogrammable (il faut juste bcp de temps libre )...

  16. #16
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Je pense que tu as p-e raison mais je demande s'il n'y a pas quand même pas un moyen. Ce qui ne va pas aux allocateurs de la STL, c'est, je pense, qu'on utilise des templates.
    Rien à voir.
    C'est juste que d'après le standard, les conteneurs ont le droit de faire certains a priori sur les allocateurs.
    Si tu veux des conteneurs qui fonctionnent avec des allocateurs plus génériques, faut prendre ceux de boost.interprocess par exemple.

  17. #17
    Membre habitué Avatar de Rodrigue
    Inscrit en
    Août 2002
    Messages
    487
    Détails du profil
    Informations forums :
    Inscription : Août 2002
    Messages : 487
    Points : 157
    Points
    157
    Par défaut
    Désolé loufoque, je ne connais pas boost.interprocess. J'ai fait une recherche sur le site de boost.org mais je n'ai rien trouvé...

  18. #18
    Expert éminent

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Points : 7 618
    Points
    7 618
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par Médinoc
    Quelle limitation?
    Si tu veux plus de mémoire virtuelle (jusqu'à 2/3Go en 32 bits), augmente simplement sa taille dans les paramètres système, non?

    Par contre, j'ignore si Windows 32 bits sait gérer plus de 2/3go AU TOTAL. Et je ne sais pas non plus pour Linux, en fait...
    En fait, il n'y a pas de limitation du swap-file à proprement parler ....
    La limitation est interne à la représentation de la mémoire: Chaque processus a son propre espace mémoire, présenté sous une forme continue. Le système se charge de paginer cet espace avec le disque, et la taille de ce fichier n'est pas vraiment limitée (enfin, pas que je sache).

    En clair, deux programmes peuvent pointer sur l'addresse 0x889783C0 et y trouver des choses différentes.

    Il est clair qu'un programme 32 bits ne peut référencer que 4Go de mémoire.
    En plus Windows a besoin de réserver un certain espace pour les I/O, l'adressage statique (PCI, AGP, ...) etc...De ce fait, par défaut, Windows x32 se reserve 2Go, et il est possible, au boot, de lui dire de n'en prendre qu'un seul.

    La limitation à 2Go est donc par processus (Windows x32 se reserve les 2 autres Go), et un flag permet d'aller jusqu'à 3Go.

  19. #19
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    http://ice.prohosting.com/newfunk/bo.../interprocess/

    Trouvé en deux secondes avec Google.
    Comme d'habitude ça se télécharge dans le boost vault.

  20. #20
    Membre habitué Avatar de Rodrigue
    Inscrit en
    Août 2002
    Messages
    487
    Détails du profil
    Informations forums :
    Inscription : Août 2002
    Messages : 487
    Points : 157
    Points
    157
    Par défaut
    Merci d'avoir pris ces deux secondes pour moi , je précise que j'ai cherché sur le site de boost mais je n'ai rien trouvé

    "Boost.Interprocess allows creating complex objects in shared memory and memory mapped files. For example, we can construct STL-like containers in shared memory."

    Cela m'a l'air très intéressant, je vais essayer d'utiliser tout ça demain au boulot. Si tu as de conseils sur comment m'y prendre, je t'écoute ...

    Merci!

Discussions similaires

  1. Créer une VM depuis un disque dur ?
    Par boufon dans le forum VMware
    Réponses: 2
    Dernier message: 30/06/2011, 20h38
  2. Temps total de lecture de fichiers depuis le disque dur
    Par Tesing dans le forum Composants
    Réponses: 1
    Dernier message: 05/12/2009, 20h14
  3. Réponses: 0
    Dernier message: 19/01/2009, 21h10
  4. Pointeur sur fonction et allocation mémoire
    Par Captain_JS dans le forum C++
    Réponses: 4
    Dernier message: 31/07/2008, 09h55
  5. Lire swf depuis le disque dur, cache: possible ?
    Par c13303 dans le forum Flash
    Réponses: 2
    Dernier message: 18/11/2006, 18h45

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo