0x90 a écrit :
Pour tes masques je ne suis pas sur que ce soit vraiment une bonne idée de les précalculer, y'a beaucoup de processeurs sur lesquels un décalage binaire est plus lent qu'un accès en mémoire ?
|
Hrum. Je crois que j'ai besoin de vacances
Citation :
Sinon y'a un truc qui m'étonne, c'est que tu veuille lister les blocs occupés et pas les blocs libres, mais j'ai peut-être raté quelque chose (j'ai vraiment lut le code en diagonale). En listant les blocs occupés, plus tu alloue de petits packets, même consécutifs, plus tu ralentis ton système (augmentation du temps de scan pour les merge). En listant les blocs libres, si tu as de nombreux blocs petits consécutifs, ta liste reste petite, et une allocation se limite à réduire par l'avant un bloc libre sans toucher à la liste (sauf si tu mange complètement un bloc, ou que tu as plusieurs listes selon la taille).
|
Si vous parlez du code et donc de l'allocateur "fixe", je fais ainsi pour réduire l'overhead au max. Si l'on excepte le header, un bloc, alloué ou non, ne consomme qu'un seul bit. Si je procède au moindre chaînage, ça va me prendre 32 ou 64 bits en plus selon la plateforme. Dans la mesure où elle sert à éviter quelque chose d'aussi lourd qu'un accès à un sgbd, je pense qu'il est raisonnable de considérer que cette mémoire est *beaucoup* plus précieuse que la cpu utilisée pour l'allouer. Par contre, chaîner les headers où il reste des blocks libres me semble être un échange intéressant.
Pour l'allocateur variable, il y a au minimum une information en plus à stocker, la taille du bloc. De mon point de vue, la question réduite à sa plus simple expression est: comment stocker cette taille au mieux? (sans y passer trois semaines non plus ) Je verrais bien les headers de morceaux avec les infos taille du plus petit et du plus grand bloc libre. Ca me laissera toujours quelques recherches pour trouver un header contenant un bloc qui va bien. Bon. Disons qu'on tombe sur un malade qui nous file 4Go. La moitié se trouve en variable. On va dire que par défaut, on se prend des morceaux de 64Ko. Ca nous fait 2^31/2^16=32k headers max potentiels. Quand c'est bien plein, ça peut craindre s'il y a beaucoup de morceaux où il ne reste pas grand chose. Si on ne prend que 512Mo dans la tronche, ça nous fait 2^12=4k et c'est pas forcément top moumoute non plus.
Citation :
Si tu veut un faible overhead de header, regarde du coté des buddy allocator avec les puissances de 2, la détermination de la taille du bloc se fait uniquement par la valeur du pointeur et les merges sont en log de la liste des libres si ma mémoire est bonne. (Par contre la frag interne peut ne pas être super bonne selon les cas d'utilisation).
|
Si j'en crois wikipedia, ça se fait uniquement ainsi pour les très petits blocs mais c'est effectivement intéressant dans la mesure où c'est avec eux que l'overhead est proportionnellement le plus important. Sinon, c'est un arbre qui est utilisé. Bon, je ne voulais pas trop m'emmerder avec ça, c'est pas gagné.