begin process at 2010 09 06 12:38:55
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Astuces

 > MEMCPY ET ZEROMEMORY

MEMCPY ET ZEROMEMORY


 Information sur la source

Note :
Aucune note
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é :5 770 / 65

Auteur : omi

Ecrire un message privé
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;
}


 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Sources du même auteur

Source avec Zip Source avec une capture VRAI CALCULETTE

 Sources de la même categorie

Source avec Zip Source avec une capture C++ FORMAT D'IMAGE AVEC QT par pop70
Source avec une capture EXEMPLE DE POINTEURS DE FONCTION par pop70
Source avec Zip Source avec une capture [C++] CLASS REGISTER par Miwik
SMART POINTEUR À COMPTEUR DE RÉFÉRENCE par nirgal76
POINTEUR INTELLIGENT par snpier wolf

Commentaires et avis

Commentaire de JackosKing le 22/07/2003 16:17:59

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

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.

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




Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Septembre 2010
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
27282930   

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,499 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales