begin process at 2008 09 06 19:24:33
1 237 892 membres
276 nouveaux aujourd'hui
14 314 membres club

Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum.
Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

MEMCPY ET ZEROMEMORY


Information sur la source

Catégorie :Astuces Niveau : Débutant Date de création : 20/07/2003 Date de mise à jour : 20/07/2003 14:23:36 Vu / téléchargé: 4 245 / 60

Note :
Aucune note

Commentaire sur cette source (3)
Ajouter un commentaire et/ou une note

Description

vu le nombre de sources se servant pour remplir ou copier un tableau d'une boucle for, j'ai pensé utile de demontré la performance des fonctions memcpy et ZeroMemory.
Je ne sait pas si ce sont les plus optimizées mais je les trouvent assez performantes (3 ou 4 fois superieur à la boucle for). Mais cela doit aussi dependre du compilateur et de l'optimisation.
Bon désolé c'est du C++ qui aurait du etre du C mais j'ai pas envie de transformer.

Source

  • #include <iostream>
  • #include <time.h>
  • #include <windows.h>
  • using namespace std;
  • #define LG 500000
  • #define DUREE 1
  • int main( void)
  • {
  • cout<< "Programme de test de l'optimization des fonctions memcpy et ZeroMemory." <<endl;
  • cout<< "Debut des tests. Veillez patienter.\n" << endl;
  • //tableau servant pour les essai.
  • int *tab1,*tab2;
  • try
  • {
  • tab1 = new int[ LG ];
  • tab2 = new int[ LG ];
  • }
  • catch(...)
  • {
  • cout<< "Erreur survenu durant l'allocation." << endl;
  • cout<< "Veillez diminuez la taille des tableaux" << endl;
  • return 1;
  • }
  • //*********************Remplissage de la memoire par des zeros************************
  • cout<< "Debut du test de remplissage par des zeros sans fonction." << endl;
  • time_t temps1 = time( NULL),temps2;
  • int comp = 0;
  • do
  • {
  • for( int i=0; i<LG; i++)
  • {
  • tab1[i] = 0;
  • }
  • comp++;
  • temps2= time( NULL);
  • }while( temps2-temps1 < DUREE );
  • cout << "il a ete fait " << comp << " remplissages complets en "<< DUREE << " secondes\n" << endl;
  • //******Remplissage de la memoire par des zeros graace a la fonction ZeroMemory********
  • cout<< "Debut du test de remplissage par des zeros avec ZeroMemory." << endl;
  • temps1 = time( NULL);
  • comp = 0;
  • do
  • {
  • ZeroMemory( (void*)tab1, LG);
  • comp++;
  • temps2= time( NULL);
  • }while( temps2-temps1 < DUREE );
  • cout << "il a ete fait " << comp << " remplissages complets en "<< DUREE << " secondes\n" << endl;
  • //************************Remplissage de la memoire par copie************************
  • cout<< "Debut du test de copie de tableau sans fonction." << endl;
  • temps1 = time( NULL);
  • comp = 0;
  • do
  • {
  • for( int i=0; i<LG; i++)
  • {
  • tab2[i] = tab1[i];
  • }
  • comp++;
  • temps2= time( NULL);
  • }while( temps2-temps1 < DUREE );
  • cout << "il a ete fait " << comp << " remplissages complets en "<< DUREE << " secondes\n" << endl;
  • //*******Remplissage de la memoire par copie gace a la fonction memcpy***************
  • cout<< "Debut du test de copie de tableaus avec memcpy." << endl;
  • temps1 = time( NULL);
  • comp = 0;
  • do
  • {
  • memcpy( (void *)tab2, (void *)tab1, LG);
  • comp++;
  • temps2= time( NULL);
  • }while( temps2-temps1 < DUREE );
  • cout << "il a ete fait " << comp << " remplissages complets en "<< DUREE << " secondes\n" << endl;
  • delete [] tab1;
  • delete [] tab2;
  • return 0;
  • }
#include <iostream>
#include <time.h>
#include <windows.h>

using namespace std;

#define LG 500000
#define DUREE 1

int main( void)
{
	cout<< "Programme de test de l'optimization des fonctions memcpy et ZeroMemory." <<endl;
	cout<< "Debut des tests. Veillez patienter.\n"  << endl;

	//tableau servant pour les essai.
	int *tab1,*tab2;

	try
	{
		tab1 = new int[ LG ];
		tab2 = new int[ LG ];
	}
	catch(...)
	{
		cout<< "Erreur survenu durant l'allocation." << endl;
		cout<< "Veillez diminuez la taille des tableaux" << endl;
		return 1;
	}

//*********************Remplissage de la memoire par des zeros************************
	cout<< "Debut du test de remplissage par des zeros sans fonction." << endl;
	time_t temps1 = time( NULL),temps2;
	int comp = 0;
	do
	{
		for( int i=0; i<LG; i++)
		{
			tab1[i] = 0;
		}
		comp++;
		temps2= time( NULL);
	}while( temps2-temps1 < DUREE );
	cout << "il a ete fait " << comp << " remplissages complets en "<< DUREE << " secondes\n" << endl;

//******Remplissage de la memoire par des zeros graace a la fonction ZeroMemory********
	cout<< "Debut du test de remplissage par des zeros avec ZeroMemory." << endl;
	temps1 = time( NULL);
	comp = 0;
	do
	{
		ZeroMemory( (void*)tab1, LG);
		comp++;
		temps2= time( NULL);
	}while( temps2-temps1 < DUREE );
	cout << "il a ete fait " << comp << " remplissages complets en "<< DUREE << " secondes\n" << endl;

//************************Remplissage de la memoire par copie************************
	cout<< "Debut du test de copie de tableau sans fonction." << endl;
	temps1 = time( NULL);
	comp = 0;
	do
	{
		for( int i=0; i<LG; i++)
		{
			tab2[i] = tab1[i];
		}
		comp++;
		temps2= time( NULL);
	}while( temps2-temps1 < DUREE );
	cout << "il a ete fait " << comp << " remplissages complets en "<< DUREE << " secondes\n" << endl;

//*******Remplissage de la memoire par copie gace a la fonction memcpy***************
	cout<< "Debut du test de copie de tableaus avec memcpy." << endl;
	temps1 = time( NULL);
	comp = 0;
	do
	{
		memcpy( (void *)tab2, (void *)tab1, LG);
		comp++;
		temps2= time( NULL);
	}while( temps2-temps1 < DUREE );
	cout << "il a ete fait " << comp << " remplissages complets en "<< DUREE << " secondes\n" << endl;


	delete [] tab1;
	delete [] tab2;

	return 0;
}
Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip

  • signaler à un administrateur
    Commentaire de JackosKing le 22/07/2003 16:17:59

    la vitesse est fonction de la longueur du buffer a effacer...

  • signaler à un administrateur
    Commentaire de omi le 22/07/2003 18:38:39

    Ben oui mais ces fonctions seront toujours plus rapide, a longueur égales, que avec une boucle for programmez a la main quelque soit la longeur de la chaine.
    Qui d'ailleur dans le programme peut etre reglé en modifiant la constante LG.

  • signaler à un administrateur
    Commentaire de zeratul67 le 26/10/2006 22:27:10

    Voici le code assembleur généré par VS, à titre d'info, suru n cas bien simple :

    for (int i = 0; i < 255; i++)
    0040101E  mov         dword ptr [i],0
    00401028  jmp         WinMain+39h (401039h)
    0040102A  mov         eax,dword ptr [i]
    00401030  add         eax,1
    00401033  mov         dword ptr [i],eax
    00401039  cmp         dword ptr [i],0FFh
    00401043  jge         WinMain+55h (401055h)
    tab[i] = 0;
    00401045  mov         eax,dword ptr [i]
    0040104B  mov         byte ptr tab[eax],0
    00401053  jmp         WinMain+2Ah (40102Ah)

    ZeroMemory(tab, 255);
    00401055  push        0FFh
    0040105A  push        0    
    0040105C  lea         eax,[tab]
    00401062  push        eax  
    00401063  call        memset (4010B0h)
    00401068  add         esp,0Ch

    Et voici le code de Memset

    ;***
    ;memset.asm - set a section of memory to all one byte
    ;
    ;       Copyright (c) Microsoft Corporation. All rights reserved.
    ;
    ;Purpose:
    ;       contains the memset() routine
    ;
    ;*******************************************************************************

            .xlist
            include cruntime.inc
            .list

    page
    ;***
    ;char *memset(dst, value, count) - sets "count" bytes at "dst" to "value"
    ;
    ;Purpose:
    ;       Sets the first "count" bytes of the memory starting
    ;       at "dst" to the character value "value".
    ;
    ;       Algorithm:
    ;       char *
    ;       memset (dst, value, count)
    ;               char *dst;
    ;               char value;
    ;               unsigned int count;
    ;               {
    ;               char *start = dst;
    ;
    ;               while (count--)
    ;                       *dst++ = value;
    ;               return(start);
    ;               }
    ;
    ;Entry:
    ;       char *dst - pointer to memory to fill with value
    ;       char value - value to put in dst bytes
    ;       int count - number of bytes of dst to fill
    ;
    ;Exit:
    ;       returns dst, with filled bytes
    ;
    ;Uses:
    ;
    ;Exceptions:
    ;
    ;*******************************************************************************

            CODESEG

            public  memset
    memset proc

            .FPO    ( 0, 3, 0, 0, 0, 0 )

            mov     edx,[esp + 0ch] ; edx = "count"
    004010B0  mov         edx,dword ptr [esp+0Ch]
            mov     ecx,[esp + 4]   ; ecx points to "dst"
    004010B4  mov         ecx,dword ptr [esp+4]

            test    edx,edx         ; 0?
    004010B8  test        edx,edx
            jz      short toend     ; if so, nothing to do
    004010BA  je          toend (40110Bh)

            xor     eax,eax
    004010BC  xor         eax,eax
            mov     al,[esp + 8]    ; the byte "value" to be stored
    004010BE  mov         al,byte ptr [esp+8]


    ; Align address on dword boundary

            push    edi             ; preserve edi
    004010C2  push        edi  
            mov     edi,ecx         ; edi = dest pointer
    004010C3  mov         edi,ecx

            cmp     edx,4           ; if it's less then 4 bytes
    004010C5  cmp         edx,4
            jb      tail            ; tail needs edi and edx to be initialized
    004010C8  jb          tail (4010FBh)

            neg     ecx
    004010CA  neg         ecx  
            and     ecx,3           ; ecx = # bytes before dword boundary
    004010CC  and         ecx,3
            jz      short dwords    ; jump if address already aligned
    004010CF  je          dwords (4010DDh)

            sub     edx,ecx         ; edx = adjusted count (for later)
    004010D1  sub         edx,ecx
    adjust_loop:
            mov     [edi],al
    004010D3  mov         byte ptr [edi],al
            add     edi,1
    004010D5  add         edi,1
            sub     ecx,1
    004010D8  sub         ecx,1
            jnz     adjust_loop
    004010DB  jne         adjust_loop (4010D3h)

    dwords:
    ; set all 4 bytes of eax to [value]
            mov     ecx,eax         ; ecx=0/0/0/value
    004010DD  mov         ecx,eax
            shl     eax,8           ; eax=0/0/value/0
    004010DF  shl         eax,8

            add     eax,ecx         ; eax=0/0val/val
    004010E2  add         eax,ecx

            mov     ecx,eax         ; ecx=0/0/val/val
    004010E4  mov         ecx,eax

            shl     eax,10h         ; eax=val/val/0/0
    004010E6  shl         eax,10h

            add     eax,ecx         ; eax = all 4 bytes = [value]
    004010E9  add         eax,ecx

    ; Set dword-sized blocks
            mov     ecx,edx         ; move original count to ecx
    004010EB  mov         ecx,edx
            and     edx,3           ; prepare in edx byte count (for tail loop)
    004010ED  and         edx,3
            shr     ecx,2           ; adjust ecx to be dword count
    004010F0  shr         ecx,2
            jz      tail            ; jump if it was less then 4 bytes
    004010F3  je          tail (4010FBh)

            rep     stosd
    004010F5  rep stos    dword ptr [edi]
    main_loop_tail:
            test    edx,edx         ; if there is no tail bytes,
    004010F7  test        edx,edx
            jz      finish          ; we finish, and it's time to leave
    004010F9  je          finish (401105h)
    ; Set remaining bytes

    tail:
            mov     [edi],al        ; set remaining bytes
    004010FB  mov         byte ptr [edi],al
            add     edi,1
    004010FD  add         edi,1

            sub     edx,1           ; if there is some more bytes
    00401100  sub         edx,1
            jnz     tail            ; continue to fill them
    00401103  jne         tail (4010FBh)

    ; Done
    finish:
            mov     eax,[esp + 8]   ; return dest pointer
    00401105  mov         eax,dword ptr [esp+8]
            pop     edi             ; restore edi
    00401109  pop         edi  

            ret
    0040110A  ret              



Ajouter un commentaire

Pub



Appels d'offres

CalendriCode

Septembre 2008
LMMJVSD
1234567
891011121314
15161718192021
22232425262728
2930     

Boutique

Boutique de goodies CodeS-SourceS