Avatar billede Lasse Novice
04. april 2005 - 21:10 Der er 14 kommentarer og
1 løsning

fast copy memory block

Jeg har 2 pointere (p1 og p2). Den ene - p1 - peger paa noget data, den anden - p2 - peger paa en destination. Hvordan kopierer jeg alt det p1 peger paa over til der hvor p2 peger paa? Lad os antage at p1 peger paa noget data der er length bytes i laengde...
Avatar billede Lasse Novice
04. april 2005 - 21:12 #1
Det skulle maaske lige siges at p2 allerede har pladsen reserveret. saa det eneste jeg skal er at kopiere dataen.
Avatar billede arne_v Ekspert
04. april 2005 - 21:13 #2
memcpy(p2, p1, nobytes);
Avatar billede bertelbrander Novice
04. april 2005 - 21:16 #3
Hvis du ved at p2 og p1 er aligned til en int og at nobytes%sizeof(int) == 0 kan det måske gøres hurtigere ved at lave en funktion der kopiere int's

Men på de fleste moderne kompilere kan du sansynligvis ikke lave noget der er hurtigere end memcpy.
Avatar billede Lasse Novice
04. april 2005 - 21:25 #4
Der ser godt ud, 15 til hver (pga det ekstra info bertelbrander kom med)
Avatar billede bertelbrander Novice
04. april 2005 - 21:28 #5
Jeg samler ikke på point.
Avatar billede arne_v Ekspert
04. april 2005 - 21:34 #6
Det gør jeg.

:-)

Jeg tror ikke på int kopierings funktionen på CPU arkitekturer med
en instruktion som kan flytte mange bytes. Kun hvis memcpy alligevel
skal lave en løkke kan der være en fordel.
Avatar billede bertelbrander Novice
04. april 2005 - 22:54 #7
Et lille testprogram:
#include <iostream>
#include <time.h>

void Func(int *p1, int *p2, int size)
{
  while(size--)
      *p1++ = *p2++;
}

int main()
{
  int *p1 = new int [1024];
  int *p2 = new int [1024];
  int counter;

  clock_t Start, End;
  Start = clock();
  for(counter = 0; counter < 1000000; counter++)
      Func(p1, p2, 1024);
  End = clock();

  std::cout << "Diff: " << (End - Start) << std::endl;

  Start = clock();
  for(counter = 0; counter < 1000000; counter++)
      memcpy(p1, p2, 1024*sizeof(int));
  End = clock();

  std::cout << "Diff: " << (End - Start) << std::endl;
  delete [] p1;
  delete [] p2;
}

Med optimering enabled kan Func gøre det næsten lige så hurtigt som memcpy:
G++: 2250/1906
Bcc32: 2297/1968
Mars: 2265/1985
Så med disse er der ikke sparet noget ved at lave sin egen memcpy.
Avatar billede Lasse Novice
04. april 2005 - 23:02 #8
interessant
Avatar billede arne_v Ekspert
04. april 2005 - 23:47 #9
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#define N 10000
#define SCALE 1000000
#define REP 3

void dummy(char *b)
{
}

int main()
{
    int i,j,k;
    int *srcptr,*dstptr;
    char src[N],dst[N];
    clock_t t1,t2,t3,t4;
    memset(src,'A',N);
    for(i=0;i<REP;i++)
    {
        t1 = clock();
        for(j=0;j<SCALE;j++)
        {
            memcpy(dst,src,N);
        }
        t2 = clock();
        printf("memcpy %d (%c)\n",t2-t1,dst[0]);
        t3 = clock();
        for(j=0;j<SCALE;j++)
        {
            srcptr = (int *)src;
            dstptr = (int *)dst;
            for(k=0;k<N/sizeof(int);k++)
            {
                dstptr[k] = srcptr[k];
            }
        }
        t4 = clock();
        printf("int loop %d (%c)\n",t4-t3,dst[0]);
    }
    return 0;
}

C:\>gcc moving.c -o moving.exe

C:\>moving
memcpy 1390 (A)
int loop 12594 (A)
memcpy 1391 (A)
int loop 12593 (A)
memcpy 1391 (A)
int loop 12594 (A)

C:\>gcc -O6 moving.c -o moving.exe

C:\>moving
memcpy 1421 (A)
int loop 2547 (A)
memcpy 1438 (A)
int loop 2562 (A)
memcpy 1422 (A)
int loop 2547 (A)

C:\>cl moving.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3052 for 80x86
Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.

moving.c
Microsoft (R) Incremental Linker Version 7.10.3052
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:moving.exe
moving.obj

C:\>moving
memcpy 2312 (A)
int loop 11047 (A)
memcpy 2312 (A)
int loop 11047 (A)
memcpy 2312 (A)
int loop 11047 (A)

C:\>cl /Ox moving.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3052 for 80x86
Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.

moving.c
Microsoft (R) Incremental Linker Version 7.10.3052
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:moving.exe
moving.obj

C:\>moving
memcpy 1015 (A)
int loop 1031 (A)
memcpy 1032 (A)
int loop 1015 (A)
memcpy 1032 (A)
int loop 1015 (A)
Avatar billede bertelbrander Novice
04. april 2005 - 23:59 #10
Så VisualC++ er blevet hurtigere end GCC.
Med Arnes program og VC 6.0 med /Ox får jeg:

memcpy 3359 (A)
int loop 20312 (A)
memcpy 3329 (A)
int loop 21421 (A)
memcpy 3422 (A)
int loop 20719 (A)

Ikke imponerende...

Borland giver:
memcpy 2765 (A)
int loop 3375 (A)
memcpy 2766 (A)
int loop 3359 (A)
memcpy 2875 (A)
int loop 3454 (A)
Avatar billede Lasse Novice
06. april 2005 - 16:31 #11
Hvad med CopyMemory... kan den ikke ogsaa goere det?
Avatar billede arne_v Ekspert
06. april 2005 - 16:40 #12
det ser det ud til

(men jeg har aldrig set pointen i at bruge en Win32 specifik funktion, når der er
en ANSI C standard funktion til det samme)
Avatar billede bertelbrander Novice
06. april 2005 - 20:27 #13
Et par hurtige hastigheds test viser at CopyMemory er meget præcis lige så hurtig/langsom som memcpy.
Så der er ikke rigtigt nogen grund til at bruge den.
Avatar billede Lasse Novice
07. april 2005 - 16:33 #14
ANSI C => portable
Win32 => Windows

Er det rigtigt???
Avatar billede arne_v Ekspert
07. april 2005 - 16:40 #15
jep
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester