Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » memcpy

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
13.05.2004, 08:52 Uhr
(un)wissender
Niveauwart


Hallo, ich will mal sehen, wie man ein gutes memcpy in C++ schreibt, also kein asm.
Zwei Sachen sind wohl noch zu tun, das alignment und das cachen.
Wie kann ich to und from so ausrichten, dass sie bspw. an einer 4er Adresse ausgerichtet sind (und wieviel bringt das an Geschwindigkeit)?
Ich habe da echt keinen Plan.

Wie sorge ich für das Vorladen in den Cache?
Habt ihr sonst noch Tipps?


C++:
void * my_memcpy(void * to, const void* from, unsigned times)
{        
    unsigned dWordTimes = times >> 2;
    times -= dWordTimes * 4;
  
    unsigned * toDWORD =
        reinterpret_cast<unsigned*>(to);
    const unsigned * fromDWORD =
        reinterpret_cast<const unsigned*>(from);
    //Vier bytesweise kopieren.
    while(dWordTimes--)
    {                
       *toDWORD++ = *fromDWORD++;
    }

    unsigned char * toWORD =
        reinterpret_cast<unsigned char*>(toDWORD);
    const unsigned char * fromWORD =
        reinterpret_cast<const unsigned char*>(fromDWORD);
    //Rest kopieren.
    while(times--)
    {  
        *toWORD++ = *fromWORD++;
    }

    return to;
}


--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
13.05.2004, 09:45 Uhr
virtual
Sexiest Bit alive
(Operator)


Also erstmal ist der Code nicht portabel, was dir wahrscheinlich auch klar ist, weil ein unsigned nicht zwingend 4 Byte hat, sondern mehr order weniger haben kann. Dh ein ansatz mit sizeof(unsigned) bzw. std::numeric_limits wäre vielversprechender.
Ausserdem ist die Ausrichtung von from und to auf 4 Bytegrenzen auch nicht der Weisheit leztzter schluss, weil
1. Kann der Performance Nachteil bei 64 Bit sytemen (zB: Tru64) gewaltig sein, wenn es nicht gleichzeitig eine 8-Byte grenze ist
2. Die Funktion nur sehr begrenzt einsetzbar wäre. Denn nimmt man mal eine Funktion, die irgendwelche Bytegrenzen voraussetzt, dann wären solche Sachen wohl nicht sinnvoll umsetzbar:

C++:
const char* ptr = "Hallo, Welt"; // ptr wird in der Regel auf einen Speicherbereich an einer 4 oder 8 Bytegrenze liegen, jedenfalls bei Optimierenden Compiler.
const char* p1 = strchr(ptr, ','); // p1 == ptr+5, also vermutlich keine 4 Bytegrenze
char buffer[4711];
memcpy(buffer, p1, min(strlen(p1)+1, sizeof(buffer))); // Hm...


--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)

Dieser Post wurde am 13.05.2004 um 09:46 Uhr von virtual editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
13.05.2004, 12:40 Uhr
ao

(Operator)



Zitat:
virtual posteteAlso erstmal ist der Code nicht portabel

Ich glaube, gerade bei memcpy & Co. wird man nur sehr selten auf portable Implementierungen treffen, weil gerade hier eng an der Zielarchitektur entlangprogrammiert wird.

@(un)wissender: Man müsste wahrscheinlich auch, bevor man in den Turbogang schaltet und DWORD-weise kopiert, erst so lange byteweise kopieren, bis die to- und from-Pointer auf DWORD-Adressen ausgerichtet sind. Dabei kann es natürlich passieren, dass sie nie beide zugleich ausgerichtet sind, so dass man den ganzen Speicherbereich im Langsamgang kopieren muss.

Zum Thema Cache-Vorladen: Es gibt in C keine standardisierten Funktionen dafür. Wenn die CPU so was kann, macht sie das entweder selbständig oder der Compiler bringt CPU-spezifische Optimierungsroutinen mit, die das an den fraglichen Stellen erledigen. Das kann über Compiler-Optionen steuerbar sein.

Dein Code sieht übrigens voll krass aus: Einerseits dreckiger Hackercode (Bitshift statt Division, Pointerarithmetik, Wortbreiten hart einkodiert), andererseits verwendest du "brave" C++-Casts, um von unsigned long* auf unsigned char* zu kommen und dekorierst die from-Pointer sogar mit const. Irgendwie schizophren ;-)

Dieser Post wurde am 13.05.2004 um 12:46 Uhr von ao editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
13.05.2004, 14:58 Uhr
(un)wissender
Niveauwart


Das mit dem sizeof ist wohl richtig.
Allerdings geht das mit dem ausrichten wohl im allgemeinen nicht, weil man ja keine Speicherstellen verschieben darf.
Egal, ich danke euch.
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: