En TP de complexit=E9 je dois effectuer des programmes ayant diff=E9rents
co=FBts O(n), O(log n), O(n!)... et voir pour quelle taille n il
tourneront pendant 3min. Pour le prog en log n, j'ai fait la recherche
d'un nombre dans un tableau tri=E9. Le probl=E8me c'est que j'arrive pas =
=E0
le faire tourner pendant 3min, en effet la taille n du tableau qu'il
faudrait est tellement grande que j'arrive pas =E0 l'allouer.
J'ai pas fait le calcul mais je suppose que c'est impossible d'allouer
la taille n=E9cessaire.
Cependant, en testant un peu, j'ai vu que sur mon pc, intel 32-bit,
sous linux, j'arrive =E0 allouer qu'environ 400Mo de m=E9moire (avec
malloc) avant que =E7a p=E8te. Or il parait que normalement on peut
allouer jusqu'=E0 3Go de mem sous linux 32-bit.
Donc j'aimerai savoir si vous avez un bout de code qui permettrait
d'allouer jusqu'=E0 3Go de m=E9moire - ou au moins un peu plus que 400Mo.
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Nicolas George
"kathan" wrote in message :
Cependant, en testant un peu, j'ai vu que sur mon pc, intel 32-bit, sous linux, j'arrive à allouer qu'environ 400Mo de mémoire (avec malloc) avant que ça pète. Or il parait que normalement on peut allouer jusqu'à 3Go de mem sous linux 32-bit. Donc j'aimerai savoir si vous avez un bout de code qui permettrait d'allouer jusqu'à 3Go de mémoire - ou au moins un peu plus que 400Mo.
Ce n'est pas exactement ça. Il y a deux choses qui peuvent limiter la mémoire que tu peux allouer : la mémoire virtuelle disponible, et l'espace d'adressage.
La mémoire virtuelle, c'est le total de la mémoire physique plus le swap. Le noyau ne peut pas allouer plus que ce total à l'ensemble des processus du système. Il fait plus ou moins de sur-réservation : promettre plus à un processus qu'il ne peut effectivement tenir compte tenu des autres processus, dans l'espoir que ça passera au final. Mais il ne fait à ma connaissance jamais de sur-réservation d'un processus sur lui-même. Ce qui fait que si un processus réclame plus de mémoire que le total de mémoire virtuelle, ça ne passera jamais.
L'espace d'adressage, c'est l'ensemble des adresses que le processeur peut manipuler. Comme Linux ne fait pas usage de la segmentation, sur un processeur 32 bits, cet espace d'adressage est de 2^32 octets, soit 4 Go. Sur un processeur de type x86_64, il semble être de 2^64, mais est en fait de seulement 2^48 (mais d'une manière qui permet les extensions futures sans accrocs). Un processus ne peut pas manipuler plus que ça de mémoire à un instant donné, et cet espace d'adressage est partagé entre différents composants du programme :
- le code du binaire lui-même, vers le tout début de l'espace d'adressage ;
- le « tas », zone de mémoire extensible dédiée aux petites allocations de mémoire, qui grossit à la demande (c'est l'appel système brk) commence ensuite, et a environ 1 Go d'espace devant lui avant la zone suivante ;
- les mappings mémoire, des zones correspondant à des fichiers sur disque (chargés au besoin ; en particulier, les bibliothèques partagées sont de ce type), à des zones anonymes (pour les grosses allocations dynamique), à la mémoire partagée, commencent vers 0x40000000 (sur les x86) ;
- la pile, commence un peu avant 0xC0000000 et croît automatiquement vers le bas, ce qui laisse 2 Go au total pour la pile et les mappings ;
- l'espace d'adresses du noyau, qui sert lorsque le noyau s'exécute pour le compte du processus pour accéder à des zones de mémoire étrangères, commence à 0xC0000000 et va jusqu'à la fin, soit 1 Go.
On peut consulter la structure d'un processus donné dans le fichier virtuel /proc/$PID/maps. C'est assez instructif.
À la vue de ce que j'ai expliqué, un processus peut allouer un peu moins d'1 Go dans son tas, et 2 Go dans ses mappings, soit presque 3 Go au total dans deux allocations contiguës.
"kathan" wrote in message
<1171979970.447088.182210@l53g2000cwa.googlegroups.com>:
Cependant, en testant un peu, j'ai vu que sur mon pc, intel 32-bit,
sous linux, j'arrive à allouer qu'environ 400Mo de mémoire (avec
malloc) avant que ça pète. Or il parait que normalement on peut
allouer jusqu'à 3Go de mem sous linux 32-bit.
Donc j'aimerai savoir si vous avez un bout de code qui permettrait
d'allouer jusqu'à 3Go de mémoire - ou au moins un peu plus que 400Mo.
Ce n'est pas exactement ça. Il y a deux choses qui peuvent limiter la
mémoire que tu peux allouer : la mémoire virtuelle disponible, et l'espace
d'adressage.
La mémoire virtuelle, c'est le total de la mémoire physique plus le swap. Le
noyau ne peut pas allouer plus que ce total à l'ensemble des processus du
système. Il fait plus ou moins de sur-réservation : promettre plus à un
processus qu'il ne peut effectivement tenir compte tenu des autres
processus, dans l'espoir que ça passera au final. Mais il ne fait à ma
connaissance jamais de sur-réservation d'un processus sur lui-même. Ce qui
fait que si un processus réclame plus de mémoire que le total de mémoire
virtuelle, ça ne passera jamais.
L'espace d'adressage, c'est l'ensemble des adresses que le processeur peut
manipuler. Comme Linux ne fait pas usage de la segmentation, sur un
processeur 32 bits, cet espace d'adressage est de 2^32 octets, soit 4 Go.
Sur un processeur de type x86_64, il semble être de 2^64, mais est en fait
de seulement 2^48 (mais d'une manière qui permet les extensions futures sans
accrocs). Un processus ne peut pas manipuler plus que ça de mémoire à un
instant donné, et cet espace d'adressage est partagé entre différents
composants du programme :
- le code du binaire lui-même, vers le tout début de l'espace d'adressage ;
- le « tas », zone de mémoire extensible dédiée aux petites allocations de
mémoire, qui grossit à la demande (c'est l'appel système brk) commence
ensuite, et a environ 1 Go d'espace devant lui avant la zone suivante ;
- les mappings mémoire, des zones correspondant à des fichiers sur disque
(chargés au besoin ; en particulier, les bibliothèques partagées sont de
ce type), à des zones anonymes (pour les grosses allocations dynamique), à
la mémoire partagée, commencent vers 0x40000000 (sur les x86) ;
- la pile, commence un peu avant 0xC0000000 et croît automatiquement vers le
bas, ce qui laisse 2 Go au total pour la pile et les mappings ;
- l'espace d'adresses du noyau, qui sert lorsque le noyau s'exécute pour le
compte du processus pour accéder à des zones de mémoire étrangères,
commence à 0xC0000000 et va jusqu'à la fin, soit 1 Go.
On peut consulter la structure d'un processus donné dans le fichier virtuel
/proc/$PID/maps. C'est assez instructif.
À la vue de ce que j'ai expliqué, un processus peut allouer un peu moins
d'1 Go dans son tas, et 2 Go dans ses mappings, soit presque 3 Go au total
dans deux allocations contiguës.
Cependant, en testant un peu, j'ai vu que sur mon pc, intel 32-bit, sous linux, j'arrive à allouer qu'environ 400Mo de mémoire (avec malloc) avant que ça pète. Or il parait que normalement on peut allouer jusqu'à 3Go de mem sous linux 32-bit. Donc j'aimerai savoir si vous avez un bout de code qui permettrait d'allouer jusqu'à 3Go de mémoire - ou au moins un peu plus que 400Mo.
Ce n'est pas exactement ça. Il y a deux choses qui peuvent limiter la mémoire que tu peux allouer : la mémoire virtuelle disponible, et l'espace d'adressage.
La mémoire virtuelle, c'est le total de la mémoire physique plus le swap. Le noyau ne peut pas allouer plus que ce total à l'ensemble des processus du système. Il fait plus ou moins de sur-réservation : promettre plus à un processus qu'il ne peut effectivement tenir compte tenu des autres processus, dans l'espoir que ça passera au final. Mais il ne fait à ma connaissance jamais de sur-réservation d'un processus sur lui-même. Ce qui fait que si un processus réclame plus de mémoire que le total de mémoire virtuelle, ça ne passera jamais.
L'espace d'adressage, c'est l'ensemble des adresses que le processeur peut manipuler. Comme Linux ne fait pas usage de la segmentation, sur un processeur 32 bits, cet espace d'adressage est de 2^32 octets, soit 4 Go. Sur un processeur de type x86_64, il semble être de 2^64, mais est en fait de seulement 2^48 (mais d'une manière qui permet les extensions futures sans accrocs). Un processus ne peut pas manipuler plus que ça de mémoire à un instant donné, et cet espace d'adressage est partagé entre différents composants du programme :
- le code du binaire lui-même, vers le tout début de l'espace d'adressage ;
- le « tas », zone de mémoire extensible dédiée aux petites allocations de mémoire, qui grossit à la demande (c'est l'appel système brk) commence ensuite, et a environ 1 Go d'espace devant lui avant la zone suivante ;
- les mappings mémoire, des zones correspondant à des fichiers sur disque (chargés au besoin ; en particulier, les bibliothèques partagées sont de ce type), à des zones anonymes (pour les grosses allocations dynamique), à la mémoire partagée, commencent vers 0x40000000 (sur les x86) ;
- la pile, commence un peu avant 0xC0000000 et croît automatiquement vers le bas, ce qui laisse 2 Go au total pour la pile et les mappings ;
- l'espace d'adresses du noyau, qui sert lorsque le noyau s'exécute pour le compte du processus pour accéder à des zones de mémoire étrangères, commence à 0xC0000000 et va jusqu'à la fin, soit 1 Go.
On peut consulter la structure d'un processus donné dans le fichier virtuel /proc/$PID/maps. C'est assez instructif.
À la vue de ce que j'ai expliqué, un processus peut allouer un peu moins d'1 Go dans son tas, et 2 Go dans ses mappings, soit presque 3 Go au total dans deux allocations contiguës.
En TP de complexité je dois effectuer des programmes ayant différents coûts O(n), O(log n), O(n!)... et voir pour quelle taille n il tourneront pendant 3min. Pour le prog en log n, j'ai fait la recherche d'un nombre dans un tableau trié. Le problème c'est que j'arrive pas à le faire tourner pendant 3min, en effet la taille n du tableau qu'il faudrait est tellement grande que j'arrive pas à l'allouer. J'ai pas fait le calcul mais je suppose que c'est impossible d'allouer la taille nécessaire. Cependant, en testant un peu, j'ai vu que sur mon pc, intel 32-bit, sous linux, j'arrive à allouer qu'environ 400Mo de mémoire (avec malloc) avant que ça pète. Or il parait que normalement on peut allouer jusqu'à 3Go de mem sous linux 32-bit. Donc j'aimerai savoir si vous avez un bout de code qui permettrait d'allouer jusqu'à 3Go de mémoire - ou au moins un peu plus que 400Mo.
Précise un peu quel langage tu utilises ! Ici il s'agit de C, vu que tu as mis le même message sur fclc. Bon, effectivement linux permet d'_adresser_ 3Go de mémoire mais, même si tu peux adresser jusqu'à 3Go de mémoire par processus, ça ne veut pas dire que tu peux en _allouer_ autant, et surtout pas en un seul morceau. Ça dépend aussi de la mémoire vive que tu as dans ta machine et de la taille de ton swap. Si tu as suffisamment de mémoire vive, utilise des "petits" blocks de quelques mégas, et normalement tu n'as aucun problème à atteindre les 3Go. En fait, par les mécanismes magiques de pagination, il est même possible d'allouer cet espace même si tu n'en disposes pas physiquement (mais tu ne pourra pas forcément t'en servir, et tu risque de te faire ton logiciel). Par contre, ne compte pas faire un seul gros tableau de 3Go...
#include <stdio.h> #include <stdlib.h> int main() { const int size = 1000000; int i; for (i = 0; i < 100000; i++) if (!malloc(size)) break; printf("Planté à : %d Mon", i); return 0; }
fleury% ./a.out Planté à : 100000 Mo
(en fait, il n'a pas planté, il a juste atteint la valeur maximale que j'avais fixé).
À comparer à :
/* Deuxième version */
#include <stdio.h> #include <stdlib.h> int main() { unsigned char *a; const int size = 1000000; int i, j; for (i = 0; i < 100000; i++) { if (!(a = malloc(size))) break; printf("Arrivé à : %d Mon", i); for (j = 0; j < size; j++) a[j] = 1; } printf("Planté à : %d Mon", i); return 0; }
fleury% ./a.out Arrivé à : 1 Mo Arrivé à : 2 Mo ... Arrivé à : 4026 Mo zsh: killed ./a.out
P.S.: tu peux constater que j'ai une machine 64-bits, tu n'atteindras donc pas les mêmes valeurs que moi.
Bonjour,
En TP de complexité je dois effectuer des programmes ayant différents
coûts O(n), O(log n), O(n!)... et voir pour quelle taille n il
tourneront pendant 3min. Pour le prog en log n, j'ai fait la recherche
d'un nombre dans un tableau trié. Le problème c'est que j'arrive pas à
le faire tourner pendant 3min, en effet la taille n du tableau qu'il
faudrait est tellement grande que j'arrive pas à l'allouer.
J'ai pas fait le calcul mais je suppose que c'est impossible d'allouer
la taille nécessaire.
Cependant, en testant un peu, j'ai vu que sur mon pc, intel 32-bit,
sous linux, j'arrive à allouer qu'environ 400Mo de mémoire (avec
malloc) avant que ça pète. Or il parait que normalement on peut
allouer jusqu'à 3Go de mem sous linux 32-bit.
Donc j'aimerai savoir si vous avez un bout de code qui permettrait
d'allouer jusqu'à 3Go de mémoire - ou au moins un peu plus que 400Mo.
Précise un peu quel langage tu utilises ! Ici il s'agit de C, vu que tu
as mis le même message sur fclc. Bon, effectivement linux permet
d'_adresser_ 3Go de mémoire mais, même si tu peux adresser jusqu'à 3Go
de mémoire par processus, ça ne veut pas dire que tu peux en _allouer_
autant, et surtout pas en un seul morceau. Ça dépend aussi de la mémoire
vive que tu as dans ta machine et de la taille de ton swap. Si tu as
suffisamment de mémoire vive, utilise des "petits" blocks de quelques
mégas, et normalement tu n'as aucun problème à atteindre les 3Go. En
fait, par les mécanismes magiques de pagination, il est même possible
d'allouer cet espace même si tu n'en disposes pas physiquement (mais tu
ne pourra pas forcément t'en servir, et tu risque de te faire ton
logiciel). Par contre, ne compte pas faire un seul gros tableau de
3Go...
#include <stdio.h>
#include <stdlib.h>
int main() {
const int size = 1000000;
int i;
for (i = 0; i < 100000; i++)
if (!malloc(size)) break;
printf("Planté à : %d Mon", i);
return 0;
}
fleury% ./a.out
Planté à : 100000 Mo
(en fait, il n'a pas planté, il a juste atteint la valeur maximale que
j'avais fixé).
À comparer à :
/* Deuxième version */
#include <stdio.h>
#include <stdlib.h>
int main() {
unsigned char *a;
const int size = 1000000;
int i, j;
for (i = 0; i < 100000; i++) {
if (!(a = malloc(size))) break;
printf("Arrivé à : %d Mon", i);
for (j = 0; j < size; j++) a[j] = 1;
}
printf("Planté à : %d Mon", i);
return 0;
}
fleury% ./a.out
Arrivé à : 1 Mo
Arrivé à : 2 Mo
...
Arrivé à : 4026 Mo
zsh: killed ./a.out
P.S.: tu peux constater que j'ai une machine 64-bits, tu n'atteindras
donc pas les mêmes valeurs que moi.
En TP de complexité je dois effectuer des programmes ayant différents coûts O(n), O(log n), O(n!)... et voir pour quelle taille n il tourneront pendant 3min. Pour le prog en log n, j'ai fait la recherche d'un nombre dans un tableau trié. Le problème c'est que j'arrive pas à le faire tourner pendant 3min, en effet la taille n du tableau qu'il faudrait est tellement grande que j'arrive pas à l'allouer. J'ai pas fait le calcul mais je suppose que c'est impossible d'allouer la taille nécessaire. Cependant, en testant un peu, j'ai vu que sur mon pc, intel 32-bit, sous linux, j'arrive à allouer qu'environ 400Mo de mémoire (avec malloc) avant que ça pète. Or il parait que normalement on peut allouer jusqu'à 3Go de mem sous linux 32-bit. Donc j'aimerai savoir si vous avez un bout de code qui permettrait d'allouer jusqu'à 3Go de mémoire - ou au moins un peu plus que 400Mo.
Précise un peu quel langage tu utilises ! Ici il s'agit de C, vu que tu as mis le même message sur fclc. Bon, effectivement linux permet d'_adresser_ 3Go de mémoire mais, même si tu peux adresser jusqu'à 3Go de mémoire par processus, ça ne veut pas dire que tu peux en _allouer_ autant, et surtout pas en un seul morceau. Ça dépend aussi de la mémoire vive que tu as dans ta machine et de la taille de ton swap. Si tu as suffisamment de mémoire vive, utilise des "petits" blocks de quelques mégas, et normalement tu n'as aucun problème à atteindre les 3Go. En fait, par les mécanismes magiques de pagination, il est même possible d'allouer cet espace même si tu n'en disposes pas physiquement (mais tu ne pourra pas forcément t'en servir, et tu risque de te faire ton logiciel). Par contre, ne compte pas faire un seul gros tableau de 3Go...
#include <stdio.h> #include <stdlib.h> int main() { const int size = 1000000; int i; for (i = 0; i < 100000; i++) if (!malloc(size)) break; printf("Planté à : %d Mon", i); return 0; }
fleury% ./a.out Planté à : 100000 Mo
(en fait, il n'a pas planté, il a juste atteint la valeur maximale que j'avais fixé).
À comparer à :
/* Deuxième version */
#include <stdio.h> #include <stdlib.h> int main() { unsigned char *a; const int size = 1000000; int i, j; for (i = 0; i < 100000; i++) { if (!(a = malloc(size))) break; printf("Arrivé à : %d Mon", i); for (j = 0; j < size; j++) a[j] = 1; } printf("Planté à : %d Mon", i); return 0; }
fleury% ./a.out Arrivé à : 1 Mo Arrivé à : 2 Mo ... Arrivé à : 4026 Mo zsh: killed ./a.out
P.S.: tu peux constater que j'ai une machine 64-bits, tu n'atteindras donc pas les mêmes valeurs que moi.
Pascal Hambourg
Salut,
const int size = 1000000;
qui ne représente pas exactement un méga-octet, mais presque.
Sisi. Je suppose que tu voulais dire "pas exactement un mébi-octet". ;-)
Salut,
const int size = 1000000;
qui ne représente pas exactement un méga-octet, mais presque.
Sisi. Je suppose que tu voulais dire "pas exactement un mébi-octet". ;-)
Sisi. Je suppose que tu voulais dire "pas exactement un mébi-octet". ;-)
Non, je veux dire que ceux qui cautionnes ces aberrations sont des abrutis.
Blaise Potard
La mémoire virtuelle, c'est le total de la mémoire physique plus le swap. Le noyau ne peut pas allouer plus que ce total à l'ensemble des processus du système. Il fait plus ou moins de sur-réservation : promettre plus à un processus qu'il ne peut effectivement tenir compte tenu des autres processus, dans l'espoir que ça passera au final. Mais il ne fait à ma connaissance jamais de sur-réservation d'un processus sur lui-même. Ce qui fait que si un processus réclame plus de mémoire que le total de mémoire virtuelle, ça ne passera jamais.
Ben, en l'occurence il semble que si. En tout cas, quand j'ai essayé tout à l'heure, il accepté de m'allouer une petite centaine de Go sans broncher (alors que je n'ai guère qu'un peu plus de 4Go de mémoire virtuelle disponible). Il a juste fait la tronche quand j'ai voulu m'en servir...
La mémoire virtuelle, c'est le total de la mémoire physique plus le swap. Le
noyau ne peut pas allouer plus que ce total à l'ensemble des processus du
système. Il fait plus ou moins de sur-réservation : promettre plus à un
processus qu'il ne peut effectivement tenir compte tenu des autres
processus, dans l'espoir que ça passera au final. Mais il ne fait à ma
connaissance jamais de sur-réservation d'un processus sur lui-même. Ce qui
fait que si un processus réclame plus de mémoire que le total de mémoire
virtuelle, ça ne passera jamais.
Ben, en l'occurence il semble que si. En tout cas, quand j'ai essayé
tout à l'heure, il accepté de m'allouer une petite centaine de Go sans
broncher (alors que je n'ai guère qu'un peu plus de 4Go de mémoire
virtuelle disponible). Il a juste fait la tronche quand j'ai voulu m'en
servir...
La mémoire virtuelle, c'est le total de la mémoire physique plus le swap. Le noyau ne peut pas allouer plus que ce total à l'ensemble des processus du système. Il fait plus ou moins de sur-réservation : promettre plus à un processus qu'il ne peut effectivement tenir compte tenu des autres processus, dans l'espoir que ça passera au final. Mais il ne fait à ma connaissance jamais de sur-réservation d'un processus sur lui-même. Ce qui fait que si un processus réclame plus de mémoire que le total de mémoire virtuelle, ça ne passera jamais.
Ben, en l'occurence il semble que si. En tout cas, quand j'ai essayé tout à l'heure, il accepté de m'allouer une petite centaine de Go sans broncher (alors que je n'ai guère qu'un peu plus de 4Go de mémoire virtuelle disponible). Il a juste fait la tronche quand j'ai voulu m'en servir...