PowerPC et DCBZ (pour Krabob)
-
Suite à une conversation avec Krabob je me suis penché sur une instruction assembleur PowerPC du nom de DCBZ qui a pour gros interet de permettre l’écriture en mémoire systeme sans charger celle ci dans les lignes de cache.
Le résultat est impressionant:
de 125 mo/sec en écriture, je passe à 520 mo/sec.
Krabob, t’en pense quoi ?
j’en pense que ton bus se roule les pouces: Ton écriture est effective uniquement dans le cache. La ou ça va te poser un gros probléme, c’est pour benchmarquer REELLEMENT les écritures maintenant: elles se réalisent n’importe quand aprés dans la ram !
Pour les autres: je prépare un article sur l’asm PPC pour gurumed.net que je mettrais en ligne lundi, cette affaire y sera expliqué.
note : tu m’inquiétes tout à coup: ce que tu benchmarquais comme étant des écritures auparavant devait être en fait des lectures implicites 😮 (désolé)
DATA CACHE BLOCK to ZERO !
re-edit: y doit y avoir une instruction asm de validation totale
du cache. aprés ta boucle d’écriture, valide, puis mesure: le tour est joué. En plus avec dcbz tu as l’assurance que le bus n’est pas venu interférer en load. Bingo.
… sinon j’en pense que la prochaine demo universe va bourrer 2x plus.
Testé sur un AOne XE G4 avec ram ECC registered.
*** MEMORY READ TEST: 16 MB buffer ***
32 BIT IU: 206.49 MB/sec
64 BIT FPU: 209.87 MB/sec
*** MEMORY WRITE TEST without DCBZ: 16 MB buffer ***
32 BIT IU: 365.58 MB/sec
64 BIT FPU: 615.1 MB/sec
*** MEMORY WRITE TEST with DCBZ: 16 MB buffer ***
32 BIT IU: 650.15 MB/sec
64 BIT FPU: 654.31 MB/sec
La différence est impressionante. PAR CONTRE, comme tu le dis, il est possible que tout ne soit pas flushé en mémoire systeme et que la fin du test reste en cache (augmentant les performances sensiblement), vu que comme tu le dis, les données ne sont pas écrite continuellement (dans le cas présent j’écris un buffer de 16 mo * 64 fois, qui doit etre écrit chaque fois que je dépasse la taille du cache, mais les quelques derniers paquet peuvent ne pas etre écrits avec ma méthode).
Autre résultat, sur mon Aone XE G3, avec une ram non ECC:
*** MEMORY READ TEST: 16 MB buffer ***
32 BIT IU: 197.26 MB/sec
64 BIT FPU: 198.18 MB/sec
*** MEMORY WRITE TEST without DCBZ: 16 MB buffer ***
32 BIT IU: 123.79 MB/sec
64 BIT FPU: 124.87 MB/sec
*** MEMORY WRITE TEST with DCBZ: 16 MB buffer ***
32 BIT IU: 521.91 MB/sec
64 BIT FPU: 522.98 MB/sec
La différence est encore plus impressionante.
Sinon, à défaut d’avoir une instruction propre pour flusher le cache, on peut toujours s’amuser à créer autant de cache lines qu’on le souhaite avec DCBZ, puisque pour créer les nouvelles, il enverra forcément les anciennes en ram.
j’en pense que ton bus se roule les pouces: Ton écriture est effective uniquement dans le cache. La
ou ça va te poser un gros probléme, c’est pour benchmarquer REELLEMENT les écritures maintenant:
elles se réalisent n’importe quand aprés dans la ram !
Ben en fait, chaque fois que les cacheslines sont validés et que le L1 est plein je pense.
Donc si tu t’amuses à écrire 16 Mo linéairement, à la fin des 16 Mo, seuls les 32 derniers ko ne sont pas encore validés.
Encore que y’a le L2 qui se fout en tampon, ça complique encore un peu la chose.
Comme je le disais mon test fait 16 mo 64 fois, le retour au début du buffer confirmant l’écriture de la fin du buffer. 16 mo fois 64, ça fait en tout 1 Go de donnée qui sont écrites. Je pense que les 32 ko non écrit voir les 512 ko non écrit du « L2 » sont « négligeables », en tout cas ça ne fausse pas GRANDEMENT le résultat.
Quand aux prochaines démos d’Universe, elles sont en rendu hardware, donc hormis quelques conneries j’ai hélas plus grand chose à optimiser, j’en suis malheureux
Hip !!
Quand aux prochaines démos d’Universe, elles sont en rendu hardware, donc hormis quelques conneries j’ai hélas plus grand chose à optimiser, j’en suis malheureux.
… la fin d’un mythe, snif…
!! qiH
/me qui n’est pas Krabob, mais qui a quand même lu ce thread, et qui le trouve très intéressant
Je viens de jeter un oeil à toutes les instructions « dcb(x) » présente dans le programming environment.
Y’a des putains de trucs à faire avec tout ça! Mais dcbz reste le plus interressant vu que c’est le plus simple à mettre en oeuvre (mais il s’applique à moins de cas cependants).
J’ai essayé dcbt pour la lecture, mais impossible de faire dépasser les 200 mo/sec à l’Aone J’ai aussi essayé en ne lisant qu’un mot sur 8 (donc une seule lecture qui vas charger toute la cache line au passage), meme résultat, 200 mo/sec, alors que ce coup ci c’était sencé mesurer le BUS.
Par contre j’ai trouvé une autre utilité à DCBZ. Celle de pouvoir lire un octet SEUL sans charger toute la cache line.
dcbz 0,10
lwz 11,0(10)
ca créé une cacheline vide et charge le mot seul sans charger le reste: Probleme, beaucoup plus tard, lorsque la cache line est validée, la zone dans laquelle on a lu l’octet se retrouve remise à zero à cause du dcbz.
A ceci, il y a un solution: DCBI, datacache block invalidate, qui assure que la cache line est invalidée et ne sera jamais réécrite en mémoire:
Il y a donc fort à parier que:
dcbz 0,10
lwz 11,0(10)
dcbi 0,10
soit la méthode la plus rapide pour lire un octet isolé sans charger toute sa cacheline. (à tester).
Plus fort encore !!!!!!!!!!
J’écris maintenant à 728 mo/sec et non plus 520 !!!
avant j’avais:
write (*
pour 125 mo/sec
puis j’ai eu:
dcbz
write (*
pour 525 mo/sec. Mais auccune garantie que la fin du buffer soit vraiment écrit.
Pour m’assurer de l’écriture temps réel du buffer, j’ai fais:
dcbz
write (*
dcbst
Pour… 728 mo/sec!!! Et la garantie (?) que c’est écrit en fastram. Pourquoi plus rapide? non utilisation du L2 peut etre?
Je suis dépassé, je m’en réfère à maitre Kakace.
Modérateurs: Il y a un énorme troll sur ce topic propre:
C’est un troll pour 2 raisons:
-ca n’a rien à foutre ici.
-c’est contraire à tout ce qui a été prouvé ici depuis des mois. (230 mo/sec en lecture sur mon ex G4 pour 220 mo/sec pour un Peg 2 G4, soit des résultats identiques)
Ca ne fait qu’entretenir du vent.
J’ai décidé de jouer le jeu, alors je vais le faire jouer aux autres.
Quand à Kakace, je l’ai contacté par mail.
Comme ça me restait dans la tete toute ces questions,
j’ai réfléchi et je me reconnecte depuis chez moi.
Effectivement, comme le cache à une logique ‘tournante’
dans tout les cas, tes dcbz+store correspondent à
une écriture par le bus et une écriture seule, point barre.
félicitation, tu viens de valider qu’une écriture
avec dcbz est (putain…) 4 fois plus rapide au bas mot
qu’une écriture sans. On sort le champagne.
Il est logique qu’un dcbt rapporte moins
en lecture,mais essaie des réglages:
oublie pas que le dcbt dois être fait
avant… mais combien de cycle avant ? on sait pas.
Par contre, ton plan pour lire un octet en random sans
lire les 32 du CL, hmmm j’y ai cru une minute, mais non:
le dcbz a dit que c’était 0, du coup il va pas vraiment
la relire. (le lbz est gruggé et va lire un 0 faux pasqu’il
croit l’avoir déjà lu.)
sinon là, t’était à 2 doigt de trouver un fake de chez fake,
la solution aux probléme d’accés random,
du grand de grand, tu pouvais te faire embaucher chez IBM ou totorola.
edit:
à tester comme tu dis… j’ai pas compris le cas ‘special’
ou le premier arg. de dcbz est ‘0’.
Effectivement, mon fake est bidon.
Dur dur lorsque l’on réfléchie de savoir mettre son cerveau dans le cache ou dans la ram à l’instant T.
pour DCBT, il n’a pas une quantité de cycle précise pour le mettre avant.
A mon avis, le CPU rappartri le block uniquement sur le temps IDLE du bus. De plus, ça dépend de ta bande passante mémoire.
Disons que sur nos machines, il faut un « temps raisonnablement long » avant
EDIT:
DSBZ rA, rB créé un block pour l’adresse rA+rB, SAUF si rA est r0… si rA est r0, il prendra rA=0, donc l’adresse concernée sera uniquement rB.
C’est exactement le meme phénomène que pour l’addition où add rC,rA,rB donne rC=rB lorsque rA=r0.
C’est juste les conditions d’utilisation habituelles de r0, rien de plus.
pour dcbt:
effectivement, avec que des load ça doit pas être trop actif.
mais si tu es dans un cas (assez courant) ou tu as:
Long calcul
Load N
Long calcul
Load N+32
Long calcul
Load N+64
…
ceci doit mega-payer:
dcbt N
Long calcul
Load N
dcbt N+32
Long calcul
Load N+32
dcbt N+64
Long calcul
Load N+64
…
Pour le miga sans cache L2 qui bourre à mort avec dcbst:
dcbst ? est-ce que ça force le store d’un CL quoi qu’il arrive ?
génial !! tu as trouvé ton modéle pour ton benchmark je pense:
si les instruction dcb(x) permettent de manipuler le cache L1,
le cache L2 lui garde un comportement d’un cache classique,
donc il doit ‘bloquer’ certains accés. si tu forces
un store de CL sans L2, zioof ! il part direct en RAM:
tes dcbz + store + dcbst imposent un flux constant d’écriture
du proc à la RAM.(condition de bench idéale pour un bus)
alors qu’avec un cache L2: meme ton dcst est soumi au bon
vouloir du L2 pour l’écriture finale en RAM (lag à terme
avec copie > taile cache L2 )
moralités: les caches sont fait pour accélérer dans la majorité
des cas, une copie bourine de mémoire étant un cas particulier.
Be aware of your cache !
Note aux défenseurs acharnés du C.
Je suppose que nos bons vieux compilos utilisent cette « optim » pour
faire des copies ram plus rapidement ? hmm ?
@Crisot : reste à voir si une instruction genre BltBitMapRastPort outruc du genre utilise cette astuce pour copier plus rapidement des
datas dans la mémoire de la carte vidéo. Est-ce que cet effet de
vitesse se ressent aussi lors de copies vers une mémoire autre que la
RAM centrale ?
Krabob: TU as tout compris
Rafo: J’ai réécris tout à l’heure justement mon benchmark en pure C optimisé de partout et compilé avec GCC 3.4 qui est à l’heure actuelle le compilo C le moins pourri que je connaisse en terme de vitesse, avec évidement le niveau d’optimisation maximal:
Verdict: 125 mo/sec.
Bye bye C.
Je doute que ce genre de trick soit utilisé par des fonctions systeme, je comptais justement en parler à l’os 4 pour proposer mes services.
Pour une copie de buffer, oui, on peut gagner du speed, en atteignant théoriquement le maximum de la vitesse de lecture autorisée. (je testerais).
EDIT: Après conversation avec Kakace, le verdict est le suivant: Il y a 2 modes pour le cache, comme on peut le voir sur PC, Write Back et Write Throug. En WriteBack, il faut tricker comme on l’explique ici, en Write through il y a fort à parier que ça speed sans auccun besoin de trick.
- Vous devez être connecté pour répondre à ce sujet.
› Forums › AmigaOS, MorphOS et AROS › Développement › PowerPC et DCBZ (pour Krabob)