Question

Je voudrais mapper un fichier en mémoire en utilisant la fonction mmap et voudrait savoir si la quantité de mémoire virtuelle sur la plate-forme actuelle est suffisante pour mapper un fichier énorme. Pour un fichier système 32 Je ne peux pas plus grande carte de 4 Go.
Serait std::numeric_limits<size_t>::max() me donner la quantité de mémoire adressable ou est-il un autre type que je tester (off_t ou autre chose)?

Comme Lie Ryan l'a souligné dans son commentaire la « mémoire virtuelle » ici est mal utilisé. La question, cependant tient: il y a un type associé à un pointeur et il a la valeur maximale qui définit la limite supérieure de ce que vous pouvez éventuellement adresse sur votre système. Quel est ce type? Est-il size_t ou ptrdiff_t peut-être?

Était-ce utile?

La solution

size_t n'est nécessaire d'être assez grand pour stocker le plus grand possible objet unique contigu. Ce peut ne pas être la même que la taille de l'espace d'adressage (sur les systèmes avec un modèle de mémoire segmentée, par exemple)

Cependant, sur les plates-formes communes avec un espace mémoire plat, les deux sont égaux, et vous pouvez donc se contenter d'utiliser size_t dans la pratique si vous connaissez la CPU cible.

En tout cas, cela ne veut pas vraiment vous dire quoi que ce soit utile. Bien sûr, un processeur 32 bits dispose d'un espace mémoire de 4 Go, et ainsi size_t est un entier non signé de 32 bits. Mais cela ne dit rien sur combien vous pouvez allouer. Une partie de l'espace mémoire est utilisé par le système d'exploitation. Et certaines parties sont déjà utilisées par votre propre application. Pour cartographier l'exécutable en mémoire (ainsi que toutes les bibliothèques dynamiques qu'il peut utiliser), pour la pile de chaque fil, la mémoire allouée sur le tas et ainsi de suite

Donc non, des trucs comme prendre la taille de size_t vous dit un peu plus sur l'espace d'adressage que vous utilisez, mais rien de très utile. Vous pouvez demander à l'OS la quantité de mémoire utilisée par votre processus et d'autres paramètres, mais encore une fois, cela ne pas vraiment vous aider beaucoup. Il est possible pour un processus d'utiliser seulement quelques méga-octets, mais ont étalés dans tant de petites allocations qu'il est impossible de trouver un bloc contigu de mémoire supérieure à 100 Mo, par exemple. Ainsi, sur une machine 32 bits, avec un processus qui utilise presque pas de mémoire, vous seriez peu de chances de faire une telle répartition. (Et même si le système d'exploitation avait une API WhatIsTheLargestPossibleMemoryAllocationICanMake() magique, que toujours ne vous aider. Il vous dira ce que vous avez besoin il y a un moment . Vous avez aucune garantie que la réponse serait toujours valable au moment où vous avez essayé de mapper le fichier.

Alors, vraiment, le mieux que vous pouvez faire est de essayer pour mapper le fichier, et voir si elle échoue.

Autres conseils

Salut, vous pouvez utiliser GlobalMemoryStatusEx et VirtualQueryEx si vous codage dans win32

La chose est, la taille d'un pointeur vous indique rien sur la quantité de cette « espace d'adressage » est en fait à votre disposition, à savoir peut être mis en correspondance comme un seul bloc contigu.

Il est limité par:

  • le système d'exploitation. Il peut choisir de ne faire un sous-ensemble de la plage d'adresses théoriquement possible à votre disposition, parce que la mémoire mappable est nécessaire aux fins de l'OS-propre (comme, par exemple, ce qui rend la carte graphique framebuffer visible, et bien sûr pour une utilisation par le système d'exploitation lui-même ).
  • limites configurables. Sous Linux / UNIX, la commande "ulimit" resp. setrlimit appel système () permet de limiter la taille maximale de l'espace d'adressage d'une application de diverses manières, et Windows a des options similaires par le biais des paramètres de registre.
  • l'histoire de l'application. Si l'application utilise la cartographie de la mémoire extensive, l'espace d'adressage peut fragmenter limiter la taille maximale des « disponibles » adresses virtuelles contiguës.
  • la plate-forme matérielle. Certains processeurs ont des espaces d'adresses avec des « trous »; un exemple de c'est 64bit x86 où les pointeurs ne sont valables que si elles sont entre 0x0..0x7fffffffffff ou 0xffff000000000000 et 0xffffffffffffffff. C'est à dire. vous avez 2x128TB au lieu de la pleine 16EB. Pensez-y comme 48 bits « signé » pointeurs ...

Enfin, ne confondez pas « mémoire disponible » et « espace d'adressage disponible ». Il y a une différence entre faire un malloc (someBigSize) et mmap (..., someBigSize, ...) parce que le premier pourrait exiger la disponibilité de la mémoire physique pour répondre à la demande alors que celle-ci exige généralement que la disponibilité d'un grand assez libre plage d'adresses.

Pour les plates-formes UNIX, une partie de la réponse consiste à utiliser getrlimit (RLIMIT_AS) car cela donne la limite supérieure pour l'invocation actuelle de votre application - comme on dit, l'utilisateur et / ou administrateur peut configurer cela. Vous êtes assuré que toute tentative de zones MMap plus grande que celle échouera.

Re votre question reformulée « limite supérieure de ce que vous pouvez éventuellement adresse sur votre système », est quelque peu trompeur; il est spécifique de l'architecture matérielle. Il y a des architectures 64 bits (x64 là-bas, sparc) dont MMU permet heureusement (uintptr_t) (- 1) adresse valide, à savoir que vous pouvez mapper quelque chose dans la dernière page d'un espace d'adressage de 64 bits. Que ce soit le système d'exploitation permet à une application de faire est si ou non encore une question tout à fait différente ...

Pour les applications utilisateur, la marque « haute » n'est pas (toujours) fixé a priori. Il est réglable sur par exemple Solaris ou Linux. C'est là getrlimit (RLIMIT_AS) entre en jeu.

Notez que à nouveau, par la spécification, il n'y aurait rien pour empêcher un design (bizarre) du système d'exploitation de choisir par exemple mettre des piles et des tas d'application d'adresses « bas » tout en mettant le code à des adresses « haut », sur une plate-forme avec des trous d'espace d'adressage. Vous auriez besoin des pointeurs pleins 64bit il, ne peut pas leur faire une plus petite, mais il pourrait y avoir un nombre arbitraire de plages « inaccessible / invalides », qui ne sont jamais mis à la disposition de votre application.

Vous pouvez essayer sizeof(int*). Cela vous donnera la longueur (en octets) d'un pointeur sur la plate-forme cible. Ainsi, vous pouvez savoir la taille de l'espace adressable est.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top