memcpy in assembly
-
Dass das Problem ziemlich kompliziert ist, zeigt schon was AMD zur Optimierung von Kopierroutinen empfiehlt:
Software Optimization Guide for AMD64 Processors schrieb:
5.13 Memory Copy
Optimization
❖ For a very fast general purpose memory copy routine, call the libc memcpy() function included
with the Microsoft or gcc tools. This function features optimizations for all block sizes and
alignments.Von daher wiederhol ich noch malen Vorschlag, Agner Fogs lib zu verwenden: das ist ein hoch optimierte, Quelloffene All-In-One Lösung – besser werdet ihr es nie hinbekommen.
-
hoch optimierte, Quelloffene All-In-One Lösung
Klingt gut! Wie aus der Werbung. Werde ich mir merken diesen maximalen Spruch.
-
This is my memcpy, I also have clear and set if you want them.
memfunc.asm
global _memcpy _memcpy: push edi push esi mov ecx, [esp+20] mov edi, [esp+12] mov esi, [esp+16] ;Move (E)CX bytes from [(E)SI] to ES:[(E)DI] cld rep movsb pop esi pop edi ret
memory.h
void memcpy(void *dest, void *src, uint32_t len);
-
Jarvix schrieb:
This is my memcpy, I also have clear and set if you want them.
Unfortunately a bad solution
-
... was würde gegen eine einfache Implementierung der memcpy() Funktion sprechen:
void* memcpy(void* dst, const void* src, size_t total_bytes) { uint32_t i = 0u; uint8_t* a = dst; const uint8_t* b = src; for (i = 0u; i < total_bytes; ++i) { a[i] = b[i]; } return dst; }
- das war's. Ich stelle mir vor, das ist die schnellste Variante, weil einfach und simpel. Inline-Assembler - zu kompliziert, Zeiger-Arithmetik - zu kompliziert, SSE, MMX & Co. - auch zu kompliziert
-
abc.w schrieb:
das war's. Ich stelle mir vor, das ist die schnellste Variante, weil einfach und simpel.
so einfach ist es aber leider nicht ...
-
Zum memset
Ihr werdet ja wahrscheinlich größtenteils Seiten benötigen, welche mit 0 beschrieben sind. Dann könntet ihr euch die Mühe ersparen zu optimieren, wenn ihr einen Task mit sehr niedriger Priorität erstellt, der zum Beispiel immer 10 genullte Pages bereitstellt, und auch nur arbeitet, sollte eine dieser 10 Seiten fehlen. (weiteres steht im Tanenbaum)
-
Die memcpy funktion benutzt in der Implementierung bei Visual C++ den rep move befehl und prüft ausserdem, ob die Länge eine ganzahlige vielfache von 4 ist, dann können in einen Takt bis zu 4 Bytes kopiert werden. Für den Rest wird dann rep movesb benutzt.
Wenn ich dann also z.B. 256 Bytes kopiere, dann brauche ich dafür nur 64 Takte statt 256, wenn ich nur Byteweise kopieren würde, also mind. 4x schneller als die Lösung von abc.w und Jarvix.
Ebenso analog arbeitet auch memmove.