Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1477 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  [memcpy] L'importance de l'optimisation dans la copie des données

 


 Mot :   Pseudo :  
 
 Page :   1  2  3
Page Précédente
Auteur Sujet :

[memcpy] L'importance de l'optimisation dans la copie des données

n°792862
christophe​_d13
L'efficacité à tout prix.
Posté le 11-07-2004 à 11:26:17  profilanswer
 

Je travaille actuellement sur memcpy (ré-écriture).
En effet, j'ai découvert que les routines officielles (intel et AMD) n'étaient pas aussi performantes que ces fondeurs pouvaient le laisser croire.
Pour illustrer mes propos, voici un graphe utilisant plusieurs routines SSE et/ou MMX, j'ai enlever les routines CPU et FPU car elles n'apportent rien de plus (et polluent le graphe)
<Erreur dans le graphe, voir plus bas>


Message édité par christophe_d13 le 11-07-2004 à 13:15:57
mood
Publicité
Posté le 11-07-2004 à 11:26:17  profilanswer
 

n°792874
christophe​_d13
L'efficacité à tout prix.
Posté le 11-07-2004 à 11:53:42  profilanswer
 

La suite... Pour ce test, on essaye de ne pas utiliser le cache (flush).
<Erreur dans le graphe, voir plus bas>


Message édité par christophe_d13 le 11-07-2004 à 13:16:06
n°792876
christophe​_d13
L'efficacité à tout prix.
Posté le 11-07-2004 à 11:57:56  profilanswer
 

Ces tests confirment largement la supériorité de la copy SSE avec movaps/movntps quand il s'agit de traîter des zones ne se trouvant pas dans le cache.
 
Attention toutefois, on effectue une copie ! Cet à dire que l'on lit puis on écrit. Certains logiciels affichent des résultats doubles.
En accès RAM, le débit entrant/sortant est de 3238Mo/s et le global de 1619Mo/s.
 
Le processeur ayant un bus de 180,409MHz soit un vitesse DDR de 360,818MHz. A chaque front, on peut transmettre 64 bits. Soit un débit théorique entrant ou sortant de 23092MBits/s soit 2886Mo/s. Alors pourquoi je suis à 3238Mo/s ? A mon avis, le Write-Back y est pour quelque chose.
 
Pour illustrer un processeur AthlonXP Barton, un test fait HFR.
http://www.hardware.fr/medias/photos_news/00/06/IMG0006225.gif
Attention, pour ce test, la mémoire est en 2-2-2-6 d'où les résultats élevés. Sandra ne dit pas si les débits sont doublés ou pas.
 
Une autre test à 200MHz avec différents timings
http://www.hardware.fr/medias/photos_news/00/06/IMG0006606.gif


Message édité par christophe_d13 le 11-07-2004 à 12:21:26
n°792933
christophe​_d13
L'efficacité à tout prix.
Posté le 11-07-2004 à 13:15:14  profilanswer
 

Enfin OUF !
J'ai compris. Il y avait un soucis dans ma routine.

J'atteind donc un débit crête de 1377Mo/s contre 1343Mo/s pour la routine d'AMD. Soit mon gain initial de 2,5% pour le débit en mode DDR.


Message édité par christophe_d13 le 11-07-2004 à 13:16:30
n°792940
Taz
bisounours-codeur
Posté le 11-07-2004 à 13:28:30  profilanswer
 

oui mais est-ce que tu as fait des mesures applicatives réelles, je veux dire, faire des memcpy en boucles, d'accord, mais dans une application de calcul (ou bien un tri, ça peut être très bien) pour évaluer ça en condition réelles, voir comment ça souille le cache ou bien les temps de bascule selon les routines. tu peux faire ça, un tri générique en C avec des memcpy, avec des tailles de données différentes ?

n°792945
christophe​_d13
L'efficacité à tout prix.
Posté le 11-07-2004 à 13:43:48  profilanswer
 

Le but final est de fournir plusieurs routines memcpy dont une permettant de faire une liste de memcpy.
Toutes ces routines utiliseront la meilleure routine selon les besoins.

n°792948
Taz
bisounours-codeur
Posté le 11-07-2004 à 13:47:45  profilanswer
 

oui, mais pour pouvoir déterminer qui réponds le mieux à quoi ...

n°792950
christophe​_d13
L'efficacité à tout prix.
Posté le 11-07-2004 à 13:50:48  profilanswer
 

Taz> C'est l'intérêt de fournir plusieurs routines au programmeur qui au final font la même chose mais de façon différentes.
 
http://kristahl.design.free.fr/Perso/Copy%20Test%20with%20cache.png
 
Up> Je travaille surtout sur les problèmes d'alignement 8/16 octets.


Message édité par christophe_d13 le 11-07-2004 à 13:53:21
n°792956
Taz
bisounours-codeur
Posté le 11-07-2004 à 13:59:52  profilanswer
 

moi, je veux voir ça dans un algorithme

n°793020
christophe​_d13
L'efficacité à tout prix.
Posté le 11-07-2004 à 17:07:16  profilanswer
 

Taz> De toute façon, t'es tout le temps en train de critiquer. Si le monde t'écoutait, on serait pas prêt d'évoluer.
Une routine relativement générique qui permet de gagner un peu de vitesse est toujours bonne à prendre.

mood
Publicité
Posté le 11-07-2004 à 17:07:16  profilanswer
 

n°793033
Taz
bisounours-codeur
Posté le 11-07-2004 à 17:52:45  profilanswer
 

mais putain, tu comprends rien !
t'auras beau montrer que l'avion va 4 fois plus vite que le train, il faut bien 2H pour embarquer/débarquer dans un voil, donc sur énormément de distances, le train est, de manière pratique, plus rapide que l'avion.

n°793049
christophe​_d13
L'efficacité à tout prix.
Posté le 11-07-2004 à 18:26:51  profilanswer
 

Si je te suis dans ton raisonnement, il faut laisser tomber l'avion...
PS: ça sert à rien de jurer.

n°793056
blackgodde​ss
vive le troll !
Posté le 11-07-2004 à 18:58:05  profilanswer
 

non, d'apres son raisonnement, il faut prendre l'avion sur des grandes distances peu frequemment et le train sur des petites distances frequemment, et jpense qu'il associe ton memcpy a l'avion et celui de l'os (vu qu'il parle de cache) au train.


---------------
-( BlackGoddess )-
n°793061
Taz
bisounours-codeur
Posté le 11-07-2004 à 19:06:49  profilanswer
 

vous me sidérez : exercice pratique. La voiture va bien plus vite que la marche (on va dire 130km/h contre 4km/h). Votre boulangerie est au coin de la rue. Allez-y a pied. Allez-y en voiture. Vous allez voir ...

n°793062
Taz
bisounours-codeur
Posté le 11-07-2004 à 19:09:19  profilanswer
 

et j'associe rien du tout : je demande un benchmark applicatif pour justement savoir qui est plus efficace.

n°793066
cricri_
Posté le 11-07-2004 à 19:29:02  profilanswer
 

On est d'accord Taz, c'est clair, n'empêche que ce genre de bench/test est intéressant à mon avis, on s'est déjà posé le problème ( K!TV pour ne pas le nommer), on a fait un paquet de tests ( c'est pas moi qui m'en suis occuppé ...), sans vraiment arriver à qq chose de top, faut dire qu'il y a plusieurs cas, copie de mémoire à mémoire ( pour les plugins), et copie de mémoire dans l'overlay à la fin; et là c'est clairement différent car on tape dans la vidéo ...
Mais bon, on s'égarre ... ;)

n°793068
Taz
bisounours-codeur
Posté le 11-07-2004 à 19:37:32  profilanswer
 

mais ou j'ai dit que c'était inintéressant ?

n°793069
cricri_
Posté le 11-07-2004 à 19:48:50  profilanswer
 

nulle part , effectivement, donc continue Christophe ! ;)

n°793070
cricri_
Posté le 11-07-2004 à 19:51:31  profilanswer
 

Et indique la source/destination, car comme déjà dit de mémoire à overlay ça n'est pas du tout pareil, enfin je pense que tes tests sont de mémoire à mémoire.

n°793094
christophe​_d13
L'efficacité à tout prix.
Posté le 11-07-2004 à 20:57:15  profilanswer
 

Mes tests ont un seul but : Fournir au programmeur plusieurs routines de copy adaptées à ses besoins.
Il y a plus d'un millier de tests qui sont effectués au démarrage de l'application pour choisir les meilleurs compromis (vitesse, taille, overlap, alignement) pour les routines :
- Copie en considérant que les données sont probalement dans le cache L1, L2 ou la mémoire
- Idem mais uniquement pour le L2 et la mémoire
- Idem mais uniquement pour la mémoire
- Copie en effectuant le meilleur compromis taille/vitesse (même si on perd des performances sur le L1).
- Et puis surtout la copie listée...
 
L'intérêt c'est bien de fournir les routines les plus rapides quel que soit l'os, le CPU, le cache ou la mémoire.
C'est pour cela que mes fonctions testent le processeur (CPUID), la vitesse et la taille des caches ainsi que la vitesse de la mémoire.

n°793195
Taz
bisounours-codeur
Posté le 12-07-2004 à 07:51:19  profilanswer
 

« Fournir au programmeur plusieurs routines de copy adaptées à ses besoins. »
 
Ariane va à 28.800km/h, mais elle est loin d'être adaptée à mes besoins

n°793217
el muchach​o
Comfortably Numb
Posté le 12-07-2004 à 09:02:52  profilanswer
 

Bah, joelf fait bien le meme genre d'optimisations avec son altivec, non ?
C'est clair que dans la plupart des applis lambda, c'est inutile voire deconseille, mais il se peut tjrs que dans qq cas particuliers (genre K!TV, avec lequel je regarde la tele d'ailleurs, merci CriCri :) ), ca serve.


Message édité par el muchacho le 12-07-2004 à 09:11:03
n°793224
Taz
bisounours-codeur
Posté le 12-07-2004 à 09:13:33  profilanswer
 

non, il fait pas du tout la même chose, lui il fait du SIMD, pas de la branlette qui accélère l'internet

n°793228
jagstang
Pa Capona ಠ_ಠ
Posté le 12-07-2004 à 09:18:56  profilanswer
 

Taz a écrit :

non, il fait pas du tout la même chose, lui il fait du SIMD, pas de la branlette qui accélère l'internet


 :love: c'est bien Taz ça  
 [:kenshirooo]


---------------
What if I were smiling and running into your arms? Would you see then what I see now?  
n°793242
el muchach​o
Comfortably Numb
Posté le 12-07-2004 à 09:39:53  profilanswer
 

Taz a écrit :

non, il fait pas du tout la même chose, lui il fait du SIMD, pas de la branlette qui accélère l'internet

 
Signe Taz ! [:alphat]  :D
 
En fait, son truc, je pense que ca peut marcher seulement si le jeu de tests au demarrage est suffisamment bien selectionne pour evaluer correctement l'utilisation de la memoire cache dans l'appli, ce qui est loin d'etre evident (il faut essayer dans de nombreuses appli differentes, gros calcul, video, quicksort par exemple), mais certainement instructif, sinon ca peut faire une excellente librairie memoire.


Message édité par el muchacho le 12-07-2004 à 09:53:21
n°793480
christophe​_d13
L'efficacité à tout prix.
Posté le 12-07-2004 à 12:42:55  profilanswer
 

Je deviens fous !
 
Etant donné que j'ai besoin de mesurer la taille des caches, j'ai donc fait plusieurs routines pour cela. Et dans la dernière, j'ai des résultats ahurissants : (j'ai converti pour les vrai Mo - 1Mo = 1048576 octets et non 1000000)
L1 = 28455Mo/s
L2 = 11884Mo/s
DDR = 2752Mo/s

 
Processeur AthlonXP 2164,91MHz (Diviseur /12)
Bus à 180,4092MHz
Débit DDR max = 23093MBits/s soit 2753Mo/s
 
Voici ma routine de test de lecture (via le CPU uniquement)
(c) 2004 Christophe Gossa, Tous droits réservés.
 
A noter que je ne mesure pas la latence de RDTSC/MOV EBX,EAX/RDTSC, et que la routine travaille sur 5 passes.

#define PROCESSORTESTREAD_MOV256RD64(x)  __asm mov     eax, [esi+ecx+  4+x]      \
                                         __asm mov     eax, [esi+ecx+  8+x]      \
                                         __asm mov     eax, [esi+ecx+ 12+x]      \
                                         __asm mov     eax, [esi+ecx+ 16+x]      \
                                         __asm mov     eax, [esi+ecx+ 20+x]      \
                                         __asm mov     eax, [esi+ecx+ 24+x]      \
                                         __asm mov     eax, [esi+ecx+ 28+x]      \
                                         __asm mov     eax, [esi+ecx+ 36+x]      \
                                         __asm mov     eax, [esi+ecx+ 40+x]      \
                                         __asm mov     eax, [esi+ecx+ 44+x]      \
                                         __asm mov     eax, [esi+ecx+ 48+x]      \
                                         __asm mov     eax, [esi+ecx+ 52+x]      \
                                         __asm mov     eax, [esi+ecx+ 56+x]      \
                                         __asm mov     eax, [esi+ecx+ 60+x]
 
#define PROCESSORTESTREAD_MOV256    __asm push    ebx                       \
                                    __asm mov     esi, pData                \
                                    __asm mov     edx, 0x7FFFFFFF           \
                                    __asm mov     ecx, lNbElements          \
                                    __asm mov     edi, 5                    \
                                    __asm add     esi, ecx                  \
                                    __asm mov     dwCycleStampSpeed, edx    \
                                    __asm neg     ecx                       \
                                    __asm mov     dwTemp0, esi              \
                                    __asm mov     dwTemp1, ecx              \
                                    __asm align   16                        \
                                    __asm _$ReadTestLoop_mov:               \
                                    __asm rdtsc                             \
                                    __asm mov     ebx, eax                  \
                                    __asm _$ReadTestReadLoop_mov:           \
                                    __asm mov     eax, [esi+ecx    ]        \
                                    __asm mov     edx, [esi+ecx+ 64]        \
                                    __asm mov     eax, [esi+ecx+128]        \
                                    __asm mov     edx, [esi+ecx+192]        \
                                    __asm mov     eax, [esi+ecx+ 32]        \
                                    __asm mov     edx, [esi+ecx+ 96]        \
                                    __asm mov     eax, [esi+ecx+160]        \
                                    __asm mov     edx, [esi+ecx+224]        \
                                    PROCESSORTESTREAD_MOV256RD64(0)         \
                                    PROCESSORTESTREAD_MOV256RD64(64)        \
                                    PROCESSORTESTREAD_MOV256RD64(128)       \
                                    PROCESSORTESTREAD_MOV256RD64(192)       \
                                    __asm add     ecx, 256                  \
                                    __asm jnz     _$ReadTestReadLoop_mov    \
                                    __asm rdtsc                             \
                                    __asm mov     esi, dwTemp0              \
                                    __asm sub     eax, ebx                  \
                                    __asm mov     ecx, dwTemp1              \
                                    __asm cmp     eax, dwCycleStampSpeed    \
                                    __asm ja      _$ReadTestNoBetter_mov    \
                                    __asm mov     dwCycleStampSpeed, eax    \
                                    __asm _$ReadTestNoBetter_mov:           \
                                    __asm dec     edi                       \
                                    __asm jnz     _$ReadTestLoop_mov        \
                                    __asm pop     ebx


 
Je vous fait une petite routine d'appel simple

Code :
  1. DWORD TestLecture ( long lNbElements, BYTE * pData )
  2. {
  3.     DWORD dwTemp0, dwTemp1;
  4.     DWORD dwCycleStampSpeed;
  5.     lNbElements &= 0x7FFFFF00; //Paquets de 256 octets uniquement
  6.     SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
  7.     SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
  8.     PROCESSORTESTREAD_MOV256
  9.     SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
  10.     SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
  11.     return dwCycleStampSpeed;
  12. }


L'avantage de la routine : Vitesse maximale avec une ligne de cache de 32 ou 64 octets.


Message édité par christophe_d13 le 12-07-2004 à 13:38:15
n°793483
christophe​_d13
L'efficacité à tout prix.
Posté le 12-07-2004 à 12:46:02  profilanswer
 

el muchacho> Il y a tellement de tests...

n°793498
christophe​_d13
L'efficacité à tout prix.
Posté le 12-07-2004 à 13:00:43  profilanswer
 

Je viens de faire un test sur un PIII-866 (133*6.5)
Débit mémoire plafonnant à plus de 1Go/s (débit également théorique).
 
Pour l'instant, je considère que le test est concluant et que ma routine est fiable.
 
Up: Sur un PIV (un serveur pas top à 2,66GHz pour 1Go de ram), j'obtiens 3616Mo/s. CPU-Z m'apprend :
- L1 Cache : 8Ko (de la daube !)
- L2 Cache : 512Ko
- FSB 133
- Bus 533
- Mémoire : 2/3/3/6


Message édité par christophe_d13 le 12-07-2004 à 13:36:12
n°793514
christophe​_d13
L'efficacité à tout prix.
Posté le 12-07-2004 à 13:23:37  profilanswer
 

En comparant d'Athlon et le P4:
L1 = 28455 contre 17337
L2 = 11884 contre 14539
RAM = 2752 contre 3616
 
Je comprend mieux pourquoi le P4 se prend des claques de la part de l'athlon. On se demande d'ailleurs à quoi sert le cache L1 chez intel... Faudrait qu'ils pensent à le passer à 32Ko.


Message édité par christophe_d13 le 12-07-2004 à 16:24:57
n°793676
el muchach​o
Comfortably Numb
Posté le 12-07-2004 à 15:32:48  profilanswer
 

christophe_d13 a écrit :

En comparant d'Athlon et le P4:
L1 = 28455 contre 14539
L2 = 11884 contre 17337
RAM = 2752 contre 3616
 
Je comprend mieux pourquoi le P4 se prend des claques de la part de l'athlon. On se demande d'ailleurs à quoi sert le cache L1 chez intel... Faudrait qu'ils pensent à le passer à 32Ko.


 
Oui, c'est bizarre que les bursts du cache L1 soient inférieurs à ceux du L2.
Sinon, ton code, tu peux le faire "portable" (Linux/FreeBSD inside) ?


Message édité par el muchacho le 12-07-2004 à 15:33:14
n°793743
christophe​_d13
L'efficacité à tout prix.
Posté le 12-07-2004 à 16:24:45  profilanswer
 

Erreur de ma part en écrivant les chiffres. Mais je confirme le peu d'importance (en cas de linear-read) du cache L1.
 
Pour le porter sous Linux, il faut tout passer en mode AT&T et j'ai pas trop le temps pour cela : "mov eax, ebx" => "movl %ebx, %eax"

n°793997
christophe​_d13
L'efficacité à tout prix.
Posté le 12-07-2004 à 21:06:49  profilanswer
 

Petite mise à jour.
 
En tout, j'ai calculé 1856 combinaisons pour :
- Type de routine (L1, L2, RAM ou compromis)
- Taille de l'overlap
- Alignement
- Taille du transfert

n°794133
christophe​_d13
L'efficacité à tout prix.
Posté le 13-07-2004 à 00:59:09  profilanswer
 

Je propose une fonction de copie nécessitant un CPU supportant SSE ou 3DNow!
Comparativement à la fonction de copie livrée avec visual C :
Sur le cache L1 : +112%
Sur le cache L2 : +41%
Sur la mémoire  : +6%
Cette routine n'est pas la plus performante, mais elle est assez simple à comprendre.

Code :
  1. void _MemoryCopy_MMX_SSE_hpf_fcache_o08_br01bw01_s0064 ( void * pTarget, void * pSource, long lSize )
  2.     {
  3.         __asm {
  4.             push        ebx
  5.             mov         eax, 568
  6.             mov         esi, pSource
  7.             xor         ebx, ebx
  8.             mov         ecx, lSize
  9.             mov         edx, 64
  10.            
  11.             mov         edi, pTarget
  12.             and         ecx, 0xFFFFFFC0
  13.             //Ne surtout pas aligner  
  14.         _$memcpy_loop:
  15.             //Occupe 4 octets de code
  16.             prefetchnta [esi+eax]
  17.            
  18.             //Occupe 64 octets de code
  19.             movq        mm0, [esi+ebx]
  20.             movq        mm1, [esi+8]
  21.             movq        [edi+ebx], mm0
  22.             movq        [edi+8], mm1
  23.             movq        mm2, [esi+16]
  24.             movq        mm3, [esi+24]
  25.             movq        [edi+16], mm2
  26.             movq        [edi+24], mm3
  27.             movq        mm4, [esi+32]
  28.             movq        mm5, [esi+40]
  29.             movq        [edi+32], mm4
  30.             movq        [edi+40], mm5
  31.             movq        mm6, [esi+48]
  32.             movq        mm7, [esi+56]
  33.             movq        [edi+48], mm6
  34.             movq        [edi+56], mm7
  35.             //Occupe 8 octets de code
  36.             add         esi, edx
  37.             add         edi, edx
  38.             sub         ecx, edx
  39.             jnz         _$memcpy_loop
  40.             emms
  41.             pop ebx
  42.         }
  43.     }


 
Voici une autre fonction plus tordue (qui n'apporte pas grand chose) mais qui, sur les cpu avec une FPU lente (6x86) permet de gratter un peu (très peu en fait 5-15%):

Code :
  1. //Routine de copie 2 à 2 : esi+ecx => edi+ecx
  2.     #define OPCODE_COPY_2BY2(opread, opwrite, reg0, reg1, offset0, offset1, offsetglobal)                    \
  3.                                                 __asm opread    reg0, [esi+ecx+offset0+offsetglobal]         \
  4.                                                 __asm opread    reg1, [esi+ecx+offset1+offsetglobal]         \
  5.                                                 __asm opwrite   [edi+ecx+offset0+offsetglobal], reg0         \
  6.                                                 __asm opwrite   [edi+ecx+offset1+offsetglobal], reg1
  7.     #define MEMCPY_PREPARE_ESI_EDI_ECX(blocsize)                                                             \
  8.                                                 __asm mov         ecx, lSize                                 \
  9.                                                 __asm mov         esi, pSource                               \
  10.                                                 __asm and         ecx, 0xFFFFFFFF^(blocsize-1)               \
  11.                                                 __asm mov         edi, pTarget                               \
  12.                                                 __asm add         esi, ecx                                   \
  13.                                                 __asm add         edi, ecx                                   \
  14.                                                 __asm neg         ecx
  15. void _MemoryCopy_MOV_____mpf_fcache_o04_br01bw01_s0064 ( void * pTarget, void * pSource, long lSize )
  16.     {
  17.         __asm {
  18.             push ebx
  19.             push ebp
  20.             MEMCPY_PREPARE_ESI_EDI_ECX(64)
  21.             align 16
  22.         _$memcpyloop:
  23.             OPCODE_COPY_2BY2(mov,mov,eax,ebx, 0,32,0)
  24.             OPCODE_COPY_2BY2(mov,mov,edx,ebp, 4, 8,0)
  25.             OPCODE_COPY_2BY2(mov,mov,eax,ebx,12,16,0)
  26.             OPCODE_COPY_2BY2(mov,mov,edx,ebp,20,24,0)
  27.             OPCODE_COPY_2BY2(mov,mov,eax,ebx,28,36,0)
  28.             OPCODE_COPY_2BY2(mov,mov,edx,ebp,40,44,0)
  29.             OPCODE_COPY_2BY2(mov,mov,eax,ebx,48,52,0)
  30.             OPCODE_COPY_2BY2(mov,mov,edx,ebp,56,60,0)
  31.             add         ecx, 64
  32.             jnz         _$memcpyloop
  33.             pop         ebp
  34.             pop         ebx
  35.         }
  36.     }


 
Par rapport à une fonction de copie plus classique par 'mov reg,mem' puis 'mov mem,reg' :
- Sur le cache L1 : +15%
- Sur le cache L2 : +6%
- Sur la mémoire : +2%
 
En comparant avec la classique memcpy de visual
- Sur le cache L1 : +18%
- Sur le cache L2 : +15%
- Sur la mémoire : +4%
 
 
Codes (c) 2004 Christophe Gossa


Message édité par christophe_d13 le 13-07-2004 à 01:02:52
n°794189
christophe​_d13
L'efficacité à tout prix.
Posté le 13-07-2004 à 08:39:02  profilanswer
 

Histoire de se prendre le choux encore un peu...
Une variante de la copie 'mov reg/mem,reg/mem' précédente :
Comparaison avec la précédente version
- Cache L1 : +5%  
- Cache L2 : +2%
- Mémoire  : 0%
 

Code :
  1. void _MemoryCopy_MOV2____mpf_fcache_o04_br01bw01_s0064 ( void * pTarget, void * pSource, long lSize )
  2.     {
  3.         __asm {
  4.             mov     ecx, lSize
  5.             mov     edx, 64
  6.             mov     esi, pSource
  7.             xor     eax, eax
  8.             mov     edi, pTarget         
  9.             and     ecx, 0xFFFFFFC0
  10.             sub     edi, 64
  11.             push ebx
  12.             push ebp
  13.         _$memcpyloop:
  14.             mov     ebx, [esi+eax]
  15.             mov     ebp, [esi+ 32]
  16.             mov     [edi+ 64], ebx
  17.             mov     [edi+ 96], ebp
  18.             lea     edi, [edi+edx]
  19.             sub     ecx, edx
  20.             mov     ebx, [esi+ 4]
  21.             mov     ebp, [esi+ 8]
  22.             mov     [edi+ 4], ebx
  23.             mov     [edi+ 8], ebp
  24.             mov     ebx, [esi+12]
  25.             mov     ebp, [esi+16]
  26.             mov     [edi+12], ebx
  27.             mov     [edi+16], ebp
  28.             mov     ebx, [esi+20]
  29.             mov     ebp, [esi+24]
  30.             mov     [edi+20], ebx
  31.             mov     [edi+24], ebp
  32.             mov     ebx, [esi+28]
  33.             mov     ebp, [esi+36]
  34.             mov     [edi+28], ebx
  35.             mov     [edi+36], ebp
  36.             mov     ebx, [esi+40]
  37.             mov     ebp, [esi+44]
  38.             mov     [edi+40], ebx
  39.             mov     [edi+44], ebp
  40.             mov     ebx, [esi+48]
  41.             mov     ebp, [esi+52]
  42.             mov     [edi+48], ebx
  43.             mov     [edi+52], ebp
  44.             mov     ebx, [esi+56]
  45.             mov     ebp, [esi+60]
  46.             mov     [edi+56], ebx
  47.             mov     [edi+60], ebp
  48.             lea     esi, [esi+edx]
  49.             jnz     _$memcpyloop
  50.             pop         ebp
  51.             pop         ebx
  52.         }
  53.     }


Code (c) 2004 Christophe Gossa


Message édité par christophe_d13 le 13-07-2004 à 08:40:53
n°794196
el muchach​o
Comfortably Numb
Posté le 13-07-2004 à 08:56:21  profilanswer
 

christophe_d13 a écrit :

Erreur de ma part en écrivant les chiffres. Mais je confirme le peu d'importance (en cas de linear-read) du cache L1.
 
Pour le porter sous Linux, il faut tout passer en mode AT&T et j'ai pas trop le temps pour cela : "mov eax, ebx" => "movl %ebx, %eax"


 
Demande à Taz, je suis sûr que ça l'intéresse. :whistle:  
Mais pour cela, il faut que tu passes ta librairie en LGPL.


Message édité par el muchacho le 13-07-2004 à 08:57:44
n°794199
jagstang
Pa Capona ಠ_ಠ
Posté le 13-07-2004 à 09:00:05  profilanswer
 

christophe_d13 a écrit :


Code (c) 2004 Christophe Gossa


:ange:


Message édité par jagstang le 13-07-2004 à 09:14:42

---------------
What if I were smiling and running into your arms? Would you see then what I see now?  
n°794200
Joel F
Real men use unique_ptr
Posté le 13-07-2004 à 09:00:27  profilanswer
 

Taz a écrit :

non, il fait pas du tout la même chose, lui il fait du SIMD, pas de la branlette qui accélère l'internet


 
LMAO ^^ je quote

n°794203
Joel F
Real men use unique_ptr
Posté le 13-07-2004 à 09:01:10  profilanswer
 

el muchacho a écrit :

Bah, joelf fait bien le meme genre d'optimisations avec son altivec, non ?


 
Ouais sauf que c'est pas des copies mémoires que j'optimise ^^

n°794304
christophe​_d13
L'efficacité à tout prix.
Posté le 13-07-2004 à 10:11:48  profilanswer
 

Après avoir testé sur plusieurs plateformes (PII, PIII, P4, AthlonXP) une trentaine de fonctions, j'en ai retenue que 13. Les autres n'apportent jamais rien et ralentissent la procédure de test :
- les classiques MOVSB et MOVSD
- 2 routines "mov reg/mem, reg/mem"
- 2 routines utilisant la FPU (pratique sur les vieilles bécanes)
- 1 routine MMX
- 2 routines SSE
- 4 routines MMX/SSE compatibles MMX/3DNow! (utilisation prefetch)
 


Message édité par christophe_d13 le 13-07-2004 à 10:17:12
n°795918
christophe​_d13
L'efficacité à tout prix.
Posté le 15-07-2004 à 00:26:11  profilanswer
 

ça avance encore.
J'ai terminé la phase de sélection du compromis.
Il ne me reste qu'à faire la routine de copie à proprement parlé qui sélectionnera la meilleure routine.
 
Je vais également inclure un test de performance pour comparer le memcpy de visual c avec ma routine.
Hélas je ne pourrait comparer avec celle de AMD, car elle ne supporte pas l'overlap inférieur à 8.
 
Le grand intérêt de ma routine c'est que chacun peu ajouter son code et le programme choisira toujours parmis le meilleur.
Actuellement, j'ai 152 tests pour chacune des 13 routines soit 3780 tests allant de 128 octets à 2Mo.
 
Au final, j'ai réussi à réduire le nombre de combinaisons à 928.


Message édité par christophe_d13 le 15-07-2004 à 00:30:17
mood
Publicité
Posté le   profilanswer
 

 Page :   1  2  3
Page Précédente

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  [memcpy] L'importance de l'optimisation dans la copie des données

 

Sujets relatifs
[ASM] Optimisation MMX/SSE d'une boucle[Java RSA] cryptage de données avec une clé publique
VBA SQL recuperer données d'un SELECTinterface et traitement données fichier
[VBA Exc] Récup de données dans un classeur fermé! (cf 2ème post)pile memoire - modification donnees
Comment transferer des donnees d'une base a l'autre ? ( access )Insertion de données excel dans un tableaux phpmyadmin
Problème avec la copie de variables[PHP/HTML] Recupéré des données vers le HTML
Plus de sujets relatifs à : [memcpy] L'importance de l'optimisation dans la copie des données


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR