30

boh, c'est un classique

mais ca m'a fait penser a l'over-commit avec les cles usb sans-fond qui annoncent plus de capacite que de memoire flash dispo.

31

./24> bienvenue dans l'informatique moderne.
Dans le monde du PC, cette technologie a été introduite par le 80386 en l'an de grâce mil neuf cent quatre-vingts cinq. Vingt ans cette année tiens, ça se fête.

32

Reste que je ne suis toujours pas convaincu tongue

Certes, l'overcommit te facilite la vie en tant que programmeur. Mais il casse une garantie fondamentale : quand j'alloue de la mémoire, je m'attends à ce qu'elle soit accessible sans provoquer d'erreur (sauf cas extrême, genre barrette mémoire défectueuse ou secteur défectueux dans la partition de swap, mais on n'attend pas des programmes qu'ils soient capables de gérer ce genre de choses normalement). Sur un système avec l'overcommit activé, ce n'est pas le cas, et mon programme peut planter par manque de mémoire de manière imprévisible. Du point de vue déterminisme, c'est inacceptable.

Je reste convaincu que ce mécanisme devrait être désactivé par défaut, et activé uniquement si l'application le demande explicitement. Idéalement via deux fonctions différentes : un malloc() classique qui garantit que la mémoire allouée est accessible, et un "malloc_overcommit()" qui est plus laxiste mais n'a pas cette garantie. Après tout, une même application peut avoir besoin des deux types de comportement.

spectras > rien à voir. Le 386 rend possible la mémoire virtuelle (possible en fait dès le 286, mais avec des limitations), mais ça n'implique pas pour autant de faire de l'overcommit, c'est un choix de conception de l'OS. (et 1985, c'était il y a 30 ans tongue)
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

33

Ouais, 20, 30, c'est plus ou moins pareil tongue

Rien à voir ? Euh, ben en fait si, c'est quand même ça la technologie qui permet de sortir des pages. Le 286 ne savait pas le faire. Alors oui il faisait de la segmentation, mais je te mets au défi de l'utiliser pour faire de l'overcommit. Parce que là c'est pas des pages de 4ko qu'il faut swapper.
En fait je suis même pas sûr qu'il soit possible de détecter un miss avec de la segmentation sans pagination.

[edit: oui non, je confirme que le 286 ne pouvait pas faire d'overcommit, car la totalité du segment doit être présent en mémoire physique - au mieux tu pouvais faire du swapping manuel de tout un processus d'un coup]

34

Zerosquare (./32) :
Certes, l'overcommit te facilite la vie en tant que programmeur. Mais il casse une garantie fondamentale : quand j'alloue de la mémoire, je m'attends à ce qu'elle soit accessible sans provoquer d'erreur (sauf cas extrême, genre barrette mémoire défectueuse ou secteur défectueux dans la partition de swap, mais on n'attend pas des programmes qu'ils soient capables de gérer ce genre de choses normalement). Sur un système avec l'overcommit activé, ce n'est pas le cas, et mon programme peut planter par manque de mémoire de manière imprévisible. Du point de vue déterminisme, c'est inacceptable.

En théorie oui. En pratique, lorsque l'overcommit s'active, tu as déjà commencé à swapper à mort, et en tant qu'utilisateur tu attends l'OOM killer comme le saint grall afin de retrouver un ordi qui fonctionne.

35

Zerosquare > La plupart des programmes qui tournent sur un OS PC grand public ont pas besoin de savoir si il reste vraiment de la RAM libre ou pas. C'est seulement quand tu vas travailler dans l'embarqué ou assimilable, que ça sera important de maîtriser tous les aspects de l'utilisation de la mémoire.

C'est un raisonnement assez simple:
Si un programme commun (pas un noyau, pas un driver, pas un truc embarqué) a besoin de RAM, c'est qu'il en a besoin, et il y a peu de chances qu'il puisse réussir à contourner le manque de mémoire d'une quelconque manière. Au mieux, il pourra crasher de manière propre, mais il faut pouvoir le faire sans allocation de mémoire…
Le fait que l'OS te valide ton allocation mémoire avec de la RAM qu'il n'a pas encore, et qu'il sache utiliser un fichier d'échange (c'est indispensable), ça évite que toutes les applications du système crash en même temps dès qu'il manque un peu de RAM…

Au final, c'est une question de stabilité.
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

36

./34> C'est pas faux.
Après j'imagine qu'un puriste du truc pourrait aussi partir du principe qu'il ne met pas de swap. La mémoire y est, ou elle n'y est pas. Ce qui nous amène à un point intéressant pour O² :

(préempté par GoldenCrystal, arf)
O²> sans overcommit, que se passe-t-il quand il n'y a plus de mémoire ? malloc renvoie NULL ? Tu vérifies systématiquement le résultat de malloc quand tu codes ? Parce que si tu ne le fais pas, ton programme plantera bien plus tôt sans overcommit que avec. Et comme l'a souligné GC, non seulement tu dois vérifier systématiquement le résultat, mais en plus tu dois gérer ce cas en étant certain de ne plus allouer du tout de mémoire.

37

O²> oh, et pour la pile au fait ?
Sans overcommit, il faudrait réserver tout l'espace dès que tu forkes. Là sur mon système, la limite de la pile est à 8Mo. J'ai 180 processus lancés, donc il faudrait que le système bloque 1,5Go de RAM pour garantir la disponibilité de toutes les pages des piles.
Je suis mal barré, vu que j'ai que 1Go de mémoire physique et 500Mo de swap sur mon laptop.

Parce que si tu acceptes de ne pas bloquer tout l'espace de la pile, mais que tu refuses l'overcommit, la gestion d'un retour NULL de malloc devient encore plus drôle : non seulement tu n'as pas le droit d'allouer de la mémoire, mais tu n'as pas non plus le droit de faire des appels de fonction (bah oui, ça alloue sur la pile).

38

Je sais bien que c'est autrement plus critique en embarqué qu'en utilisation desktop classique, mais même sur un desktop ça ne me plaît pas tongue

Pour le fait qu'on ne puisse pas contourner un manque de mémoire, je ne suis pas d'accord :

- exemple simple : dans un soft qui gère des documents lourds (retouche photo, CAO, etc.), j'ai déjà plusieurs documents ouverts, et je veux en ouvrir un nouveau. Je préfère que l'allocation mémoire échoue, ce qui permet au soft de me prévenir qu'il est à court de RAM et qu'il faut fermer un ou plusieurs documents avant d'en ouvrir un nouveau, plutôt que ça se mette à ramer voir à crasher violemment sans prévenir. (Au besoin, on peut proposer à l'utilisateur d'ouvrir le document quand même à ses risques et périls).

- exemple un peu plus évolué : imaginons que j'ai un cache interne dans mon soft (disons pour éviter de refaire des calculs lourds). Si je veux que le soft tire parti des machines qui ont beaucoup de RAM, mais puisse continuer à fonctionner avec des perfs moins bonnes sur les machines avec peu de RAM, je vais dimensionner le cache suivant la RAM dispo. Avec l'overcommit, le système va me renvoyer une valeur exagérément optimiste, et se mettre à ramer comme un fou/fermer l'appli dès que je vais me mettre à utiliser concrètement la mémoire.

Enfin, ce genre de mécanismes par défaut incite les développeurs à être paresseux et à ne pas réfléchir à la conception de leurs softs. Et on voit bien ce que ça donne en pratique... tsss
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

39

spectras > pareil pour la pile. Dans la majorité des cas, 8 Mo de pile c'est largement surdimensionné. Mais vu que c'est par défaut, et qu'allouer sur la pile c'est plus simple que de faire des allocations mémoires, ben tout le monde y va à fond sans se poser de questions, en croisant les doigts pour que le système arrive à se démerder.
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

40

void* zerosquare_malloc(size_t size) { void* ptr = malloc(size); if (ptr) memset(ptr, 0, size); return ptr; }
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

41

grin

Mais je privilégierais de remplir avec des octets aléatoires. Rien ne dit qu'un OS ne serait pas assez malin pour détecter les pages qui ne contiennent que des zéros ou qui sont identiques entre elles, et faire du copy-on-write embarrassed
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

42

./40: Allons ! Tu sais bien que Zerosquare utilise calloc et pas malloc !

43

(à vrai dire, sur mes projets embarqués, y'a généralement aucune allocation dynamique. Mais bref ^^)
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

44

./42 : on sait jamais, rien ne dit que l'OS n'est pas assez malin pour faire de l'overcommit même avec calloc et faire la mise à zéro seulement à la première utilisation embarrassed
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

45

Zerosquare (./41) :
Mais je privilégierais de remplir avec des octets aléatoires. Rien ne dit qu'un OS ne serait pas assez malin pour détecter les pages qui ne contiennent que des zéros ou qui sont identiques entre elles, et faire du copy-on-write embarrassed
Un OS je sais pas, mais VMWare ESX/Server fait ça depuis sa version 2. Il a un process background qui hashe les pages. Quand ça matche, il examine les pages et, si elles sont identiques, il les met en CoW.

C'est très efficace car quand tu as 30 VM qui ont chacune une copie du même OS, il y a beaucoup de pages identiques, et une probabilité qu'elles changent quasiment nulle.


Du coup pour le zerosquare_malloc, si tu veux être raisonnablement sûr le mieux c'est d'initialiser la zone avec un générateur aléatoire cryptographique. Avec un générateur ordinaire, l'os pourrait juste stocker le seed initial après tout.

46

Zerosquare (./38) :
Au besoin, on peut proposer à l'utilisateur d'ouvrir le document quand même à ses risques et périls

Tu te rends compte que ce que tu proposes fait que chaque soft doit s'enquérir régulièrement de la mémoire dispo, et décider de l'attitude à adopter en fonction de ce qui reste, et qu'il estimera suffisant ou non ? Sachant que chaque soft aura bien sûr sa politique à ce niveau.

Je trouve le post de Golden très censé, encore une fois il n'y a pas une solution technique ultime, mais plusieurs suivant les besoins et les impératifs (sécurité, fiabilité, réactivité, bref).

(bon je dis ça, mais j'en suis encore à découvrir l'Amérique et à faire des "oh" et des "ah" à chacun de vos posts, donc mon avis vaut pas tripette grin)

47

Je viens d'essayer ça sous Windows et c'est ce qui se passe avec PaintShop Pro. J'ai créé de nouvelles images de 20000 par 20000 pixels en 16 bits par canal. Après en avoir créé 27, PaintShop Pro m'a affiché un message m'indiquant que la mémoire serait insuffisante pour continuer et que je devais fermer quelques images ou programmes pour en libérer. J'ai fait Ok et j'ai continué à créer des images. Et ça a fini par planter ^^
avatar

48

Zerosquare (./38) :
Enfin, ce genre de mécanismes par défaut incite les développeurs à être paresseux et à ne pas réfléchir à la conception de leurs softs. Et on voit bien ce que ça donne en pratique... tsss


Oui voila pourquoi un browser sur un telephone moderne va te manger 1/2 gigas de ram par page alors que sur une vieille machine on affiche la meme page sur des machines avec 4 mégas de ram.
Zerosquare (./39) :
Dans la majorité des cas, 8 Mo de pile c'est largement surdimensionné.


Et moi parfois j'ai honte avec une pile de 512 octets en me demandant si je mange pas de trop !!

Zerosquare président (des codeurs qui se sortent les doigts de l'ASS tongue )

GT Sans Ram tongue
avatar
Accrochez vous ca va être Cerebral !!

49

Zerosquare (./39) :
spectras > pareil pour la pile. Dans la majorité des cas, 8 Mo de pile c'est largement surdimensionné.

Et dans d'autres cas, c'est largement sous-dimensionné Et ca oblige les gens à faire des malloc alors qu'allouer sur la pile permettrait d'être plus rapide, plus sûr et être exception safe (et donc tout ce qui va avec).
Franchement 8Mo sur un système d’aujourd’hui c'est 0.04% de la mémoire ! C'est rien. Et si c'est pas consommé par le programme, avec l'overcommit, c'est pas consommé du tout wink Surtout sur un système 64 bits où on pourrait allouer une pile gigantesque. On me fait dire comment pourrait-on détecter les récursions infinis ? (Bof, ça arrive pas souvent mais je n'y ai pas plus réfléchi).

50

J'ai mis à jour les résultats en ./1

La différence entre win 7 et win 8.1 me surprend cheeky

./13: GoldenCrystal : c'est quoi ta config ?
./14: Oui on pourrait aussi faire comme cela. Il reste à savoir si ca serait plus représentatif.

51

Moi je suis surtout curieux sur une chose, la pile étant un emplacement mémoire, toutes les données y transitant, passerons par le cache mémoire. Le programme va faire des accès a d'autres zones mémoires, est ce que cela 'pourrit' pas les performances ? Car ces données auront très peu de chances d'être contigués. Donc remplissage du cache a chaque accès pile et reremplissage car accès a des données beaucoup lus loin non ?

L'utilisation 'exagéré' de la pile est spécique aux langages de haut niveau, car en assembleur, a part vouloir faire du récursif, et les appels au procédures (Pour le stockage du PC car perso j'utilise les regs du proc pour faire le passage de paramêtres (Bon après c'est sur cela des codeurs)).

PpHd : c'est 0.04% d'un systême

Heu cela dépend du systême, ceux qui font de l'embarqué doivent pas penser pareil. Prends une machine a café dans les entreprises, tu penses qu'elle embarque 1 Gigas ? wink


GT grin
avatar
Accrochez vous ca va être Cerebral !!

52

GT Turbo (./51) :
Le programme va faire des accès a d'autres zones mémoires, est ce que cela 'pourrit' pas les performances ? Car ces données auront très peu de chances d'être contigués. Donc remplissage du cache a chaque accès pile et reremplissage car accès a des données beaucoup lus loin non ?

Non, le cache (enfin les caches, car il y a plusieurs niveaux de caching) fonctionne par lignes. Une ligne de cache c'est quelques poignées d'octets. Chaque ligne est indépendante et peut cacher une partie différente de la mémoire.

Regarde cette question : http://stackoverflow.com/questions/3928995/how-do-cache-lines-work

53

Ah oui merci pour le rappel et dire que j'ai lu de la doc technique sur les caches du 030 il y a 3 jours (Moi j'ai un problême de mémoire tongue).

GT smile
avatar
Accrochez vous ca va être Cerebral !!

54

GT Turbo (./51) :
L'utilisation 'exagéré' de la pile est spécique aux langages de haut niveau, car en assembleur, a part vouloir faire du récursif, et les appels au procédures (Pour le stockage du PC car perso j'utilise les regs du proc pour faire le passage de paramêtres (Bon après c'est sur cela des codeurs)).

On a pas tous la même façon de coder cheeky
Le stack fait un excellent emplacement pour les variables globales et statiques, sans relogement. smile

55

GT Turbo (./51) :
>>PpHd : c'est 0.04% d'un systême
Heu cela dépend du systême, ceux qui font de l'embarqué doivent pas penser pareil. Prends une machine a café dans les entreprises, tu penses qu'elle embarque 1 Gigas ? wink.gif?8

Dans ce genre d'appareil, tu alloues la taille que tu veux à la pile du moment que l'ensemble (stack + data + bss + code) rentre dans la mémoire. Et je suis plutôt doué pour faire des trucs dans peu de places. Certaines personnes m'en remercient encore wink

56

cheeky

57

./50 > MBP Retina, Windows 8.1, 8 Go
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

58

PpHd (./50) :
La différence entre win 7 et win 8.1 me surprend cheeky


Au vu des résultats de ./1, j'ai l'impression que Windows 8.1 commence à faire de l'overcommit.

59

linux mint laptop lenovo G850

mint ~ # uname -a
Linux mint 3.13.0-24-generic #47-Ubuntu SMP Fri May 2 23:30:00 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

mint ~ # cat /proc/meminfo
MemTotal:        8039344 kB
MemFree:         4687428 kB
Buffers:          166068 kB
Cached:          1282892 kB
SwapCached:        93864 kB
Active:          1890260 kB
Inactive:        1040836 kB
Active(anon):    1127192 kB
Inactive(anon):   532092 kB
Active(file):     763068 kB
Inactive(file):   508744 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:       8249340 kB
SwapFree:        8056268 kB
Dirty:                36 kB
Writeback:             0 kB
AnonPages:       1408856 kB
Mapped:           216908 kB
Shmem:            177148 kB
Slab:             293436 kB
SReclaimable:     256068 kB
SUnreclaim:        37368 kB
KernelStack:        3672 kB
PageTables:        23444 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:    12269012 kB
Committed_AS:    3607828 kB
VmallocTotal:   34359738367 kB
VmallocUsed:      409344 kB
VmallocChunk:   34359321212 kB
HardwareCorrupted:     0 kB
AnonHugePages:    411648 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:     2207992 kB
DirectMap2M:     6043648 kB

mint ~ # echo 2 > /proc/sys/vm/overcommit_memory
mint ~ # ./a.out 
Max allocatable virtual memory=8.250000Gb

mint ~ # echo 0 > /proc/sys/vm/overcommit_memory
mint ~ # ./a.out 
Max allocatable virtual memory=63787.500000Gb
mint ~ # ./a.out 
Max allocatable virtual memory=65947.500000Gb
mint ~ # ./a.out 
Max allocatable virtual memory=65988.000000Gb
mint ~ # ./a.out 
Max allocatable virtual memory=64611.000000Gb
mint ~ # ./a.out 
Max allocatable virtual memory=64651.500000Gb
mint ~ # ./a.out 
Max allocatable virtual memory=64638.000000Gb
mint ~ # ./a.out 
Max allocatable virtual memory=64813.500000Gb

ca change selon les appels.
l'overcommit etait active par defaut.

60

Merci. résultat mis à jour. Je suis surpris que tu ne sois qu'à 8Gb sans overcommit.