Tu n'as jamais access explicitement au cache, le cache est entierement controlle par les access que tu fais a la memoire.
On peut aussi demander au cache de precacher une partie des donnes de facon a eviter des defaut de cache successif, mais la masse de donnnees transferer depuis la memeoire vers le cache reste la meme. (soit avec des instructions zarbi du processeur, ou en accedeant de la memoire "pour rien" ou encore, en utilisant un thread auxiliaire.)
Souvent, on cherche a ameliorer la localite des access a la memoire ou a reduire le montant de memoire utiliser.
Passer de int a short permet de couper l'allocation memoire en deux exemple. Si tu n'as pas besoin de valeur superieur a 65K, tu viens de permettre a ton tableau de rentrer en cache. Si tu as une structure de donne qui fait 3 octets, il y a fort a parier que ton compilateur/langage aligne sur 4 octets et "gaspille" 1/4 de la memoire, retirer l'alignement manuellement permet de gagner significativement des performances. Tu peux aussi voir pour compresser tes donnees. Il y a plein de cas, ou tu peux representer tes donnees dans une autre forme plus compacte et qui va permettre de rentrer en cache.
L'autre technique est de changer comment on accede au donnees en reecrivant l'algo. Un exemple classique est le floutage d'une image qui typiquement s'ecrit comme ca:
for (int i=0; i<N; i++) for (int j=0; j<M; j++) new[i][j] =
old[i][j]+old[i-1][j]+old[i+1][j]+old[i][j-1]+old[
i][j+1];
(oui, je sais, les access au bord tout ca...)
Regarde visuellement comment tu accedes a la memoire dans un cas comme ca. les lignes de l'image sont acceder par groupe de 3. quand tu traites la ligne 5, tu accedes a la ligne 4 et 6. Quand tu vas traiter la ligne 6, tu accedera a la ligne 5 et 7. Si ton image est tres grande, quand tu traite la ligne 6, la ligne 5 n'est deja plus en cache (parceque M est tres grand). Du coup, tu te retrouve a charger cache ligne de old 3 fois. A la place, tu peux decouper ton image en bloc de taille calcule pour que ca tienne en cache. Et traiter l'image par bloc. Ainsi l'image n'est charge qu'une seule fois en memoire. Pour plus d'information, regarde la notion de Z-order et comment ecrire le produit de matrice par matrice (dense).
Donc le meilleur moyen c'est de découper nos données pour les faire rentrer dans le cache et d'itérer sur ces blocs plutôt que sur la donnée entière.
Du coup si on sait que ça va dépasser 4MB par exemple, on se débrouille pour découper ça en bloc de 4MB et puis de les traiter un à un.
En tout cas merci pour la réponse, et bonne fête de Noël à tous le monde ![]()
c'est l'idee.
Eviter les structures creuse ou les structures a base de pointeur. Quand on a pas le choix, preallouer les zones de memoire dans un ou plusieurs pool de memoire continue. Ce genre de truc.
Note que le systeme d'exploitation peut t'indiquer pas mal de statistique sur l'utilisation des caches par un processus.
Sous linux (kernel > 2.6.31), on trouve l'outil "perf stat" qui rapporte des statistiques utiles. On peut avoir grosso modo, des estimations par ligne de code avec "perf record" et "perf annotate". On peut avoir une estimation plus precise avec cachegrind, mais c'est un environement simule qui a d'autres probleme de precision.
PS: et joyeux noel a tout le monde. ![]()
joyeux noel. ![]()
Joyeux Noël à tous ![]()
http://webcache.googleusercontent.com/search?q=cache%3aJa9dLgwsmWQJ%3ajobs.gamasutra.com/jobseekerx/viewjobrss.asp%3Fcjid%3D22685%26accountno%3D358+suckerpunch.com+create+a+queue&cd=1&hl=en&ct=clnk&gl=us
Sympa le test avant de postuler à Sucker Punch Productions à l'époque.
L'idée est de recréer une pile FIFO sans utiliser malloc.
Dans l'idée Q serait juste une struct avec un tableau de char de 2048 et un compteur.
Par contre aucune idée de la solution la plus rapide pour décaler tous les byte dans le tableau quand on push ou pop.
J'imagine que simplement les décaler d'une case n'est pas la méthode la plus véloce quand la pile est presque pleine. :/
Je viens de dire une bétise, il semble qu'on utilise le même pool de mémoire de 2048 bytes pour toutes les queues. Mais par contre, sans utiliser malloc, comment on peut retourner un pointeur Q à partir de create ? ![]()
Ah ok on sait qu'il y a au max 64 queues ça nous permet de travailler sur un pool de type Q préalloués.
La solution vers laquelle je me dirige :
Je vais découper les datas en block de 16 ou 32 bytes. 15/31 bytes de données et un byte qui permet de récupérer l'index du next block.
Puis dans Data[2048]
Le byte 0 servira de "freelist" et contiendra l'adresse du prochain bloc libre.
De 1 à 64*sizeof(Q struct) : Nos handlers de queues
Puis ensuite on aura nos blocs.
Ma struct Q serait composé à priori de l'adresse de la queue et la tête et de l'offset de la donnée de tête dans la tête et la donnée de queue dans la queue. Un bit utilisé pour savoir si la queue est utilisée ou non.
J'ai pas fait les calculs pour savoir combien de bits il me faut pour stocker les index de chaque bloc en fonction de la taille des blocs, et pour arriver à en avoir assez pour arriver au cas moyen de 15 queue 80 bytes. Je verrai demain. Ca va jouer serrer entre des blocs de 16 et 32 bytes et des index sur 6 ou 7 bits à mon avis ^^
J'essayerai d'implémenter demain ou prochainement.
Par contre j'ai mit bien plus d'une heure à trouver une bonne méthode en cherchant bien sur le net. Il me faut encore m'exercer (mais bon c'est pour un post de senior à l'origine alors ça me rassure un minimum ^^)
Oublie pas d'aligner ton Data[].
Un tableau alloué statiquement n'est pas forcément aligné en mémoire ?
J'avais fini, et puis j'ai remarqué que c'était toutes les listes qui se partageaient le tableau de 2048, et pas un tableau de 2048 pour chaque
C'est déjà plus compliqué ![]()
Enfin, j'ai ça moi:
http://pastebin.com/yMgqa662
Je ferai le 2048 une autre fois ![]()
Héhé, t'inquiête pas, j'ai aussi eu du mal à déchiffrer, mais à priori c'est bien un pool de 2048 partagé pour stocker toutes les variables. Donc y compris les structures de données qui représentent les queues.
@paulop: si c'est aligne, mais pas forcement aligne sur une cache line
Effectivement, c'est pour ça que j'essaye d'avoir des blocs les plus larges possible, histoire d'éviter de trop mélanger les données. Mais bon je pense que 32 bytes ça va être juste, le plus optimal semble être 16, pour des cache line qui sont en général de 64 bytes. Mais bon c'est plus pour l'exercice, après il faut s'adapter à la plateforme.
Puis faut que je trouve du temps pour faire ça au calme pendant 1h.
dites, je suis bientôt unemployed.
il y a des sites qui répertorient des annonces pour travailler dans l'informatique, côté programmation? ![]()
http://www.gamasutra.com/jobs/
Tu as celui-là pour les jobs dans des boites de jv aux US. ![]()