Frage

Gibt es schnellere Alternativen () in C ++ zu MEMCPY?

War es hilfreich?

Lösung

unwahrscheinlich. Ihr Compiler / Standardbibliothek wird wahrscheinlich eine sehr effiziente und maßgeschneiderte Umsetzung von memcpy. Und Memcpy ist im Grunde die niedrigste api es für das Kopieren eines Teils des Speichers zu einem anderen ist.

Wenn Sie weitere speedups wollen, einen Weg finden, keine Speicherkopieren müssen.

Andere Tipps

Als erstes wird ein Wort der Beratung. Es sei angenommen, dass die Leute, die Ihre Standardbibliothek geschrieben sind nicht dumm. Wenn es ein schnellerer Weg ist eine allgemeine Memcpy zu implementieren, würden sie es getan haben.

Zweitens, ja, es gibt bessere Alternativen.

  • In C ++, verwenden Sie die std::copy Funktion. Es macht das gleiche, aber es ist 1) sicherer, und 2) möglicherweise schneller in einigen Fällen. Es ist eine Schablone, was bedeutet, dass es für bestimmte Arten spezialisiert sein kann, ist es möglicherweise schneller als die allgemeine C Memcpy zu machen.
  • Sie können aber Ihr überlegenes Wissen von Ihre spezifische Situation nutzen. Die Implementierer von memcpy hatte, es zu schreiben, so dass es eine gute Leistung in alle Fall. Wenn Sie spezifische Informationen über die Situation haben, wo Sie sie brauchen, könnten Sie in der Lage sein, eine schnellere Version zu schreiben. Zum Beispiel, wie viel Speicher brauchen Sie zu kopieren? Wie ist es ausgerichtet? Das könnte Ihnen ermöglichen, eine effizientere Memcpy für diese speziellen Fall zu schreiben. Aber es wird nicht in den meisten anderen Fällen so gut sein (wenn es werde überhaupt funktionieren)

Optimierung Experte Agner Fog optimiert Speicherfunktionen veröffentlicht: http://agner.org/optimize/#asmlib . Es ist unter der GPL though.

Vor einiger Zeit sagte Agner, dass diese Funktionen sollten GCC builtins ersetzen, weil sie viel schneller sind. Ich weiß nicht, ob es seitdem getan worden ist.

Diese Antwort für eine sehr simiar Frage (etwa memset()) gilt auch hier.

Es sagt im Grunde, dass Compiler einig sehr optimalen Code für memcpy() / memset() erzeugen -. Und anderen Code in Abhängigkeit von der Art der Objekte (Größe, Ausrichtung, etc.)

Und denken Sie daran, nur memcpy() PODs in C ++.

Um eine schnelle Speicherkopierroutine zu finden oder zu schreiben, sollten wir verstehen, wie Prozessoren arbeiten.

Prozessoren seit Intel Pentium Pro tun „Out-of-Order-Ausführung“. Sie können viele Befehle parallel ausführen, wenn die Anweisungen Abhängigkeiten nicht haben. Dies ist aber nur dann der Fall, wenn die Anweisungen nur mit Registern arbeiten. Wenn sie mit Speicher, zusätzliche CPU-Einheiten verwendet werden, arbeiten, die so genannte „Ladeeinheiten“ (um Daten aus dem Speicher zu lesen) und „Speichereinheiten“ (zum Schreiben von Daten in dem Speicher). Die meisten CPUs haben zwei Lasteinheiten und eine Speichereinheit, das heißt, sie in zwei parallelen Befehle ausführen kann, die aus dem Speicher und eine Anweisung liest, die in den Speicher schreibt (wieder, wenn sie sich gegenseitig nicht beeinflussen). Die Größe dieser Einheiten ist in der Regel die gleiche wie die maximale Registergröße - wenn die CPU XMM Register (SSE) hat - es ist 16 Bytes, wenn es YMM Register (AVX) hat - es 32 Bytes, und so weiter. Alle Anweisungen, die Speicher zu lesen oder schreiben sind Mikrooperationen (Mikro-ops) übersetzt, die mit dem gemeinsamen Pool von Mikro-Ops gehen und dort warten, bis die Lade- und Speichereinheiten der Lage sein, sie zu dienen. Eine einzelne Lade- oder Speichereinheit kann zu einem Zeitpunkt nur einen Mikrobefehl dienen, unabhängig von der Datengröße zu laden oder zu speichern es muss, sei es 1 Byte oder 32 Byte.

So wäre schnellste Speicherkopie bewegen und aus den Registern mit maximaler Größe. Für AVX-fähige Prozessoren, schnellster Weg, um Speicher zu kopieren wäre die folgende Sequenz zu wiederholen, loop-entrollt:

vmovdqa     ymm0,ymmword ptr [rcx]
vmovdqa     ymm1,ymmword ptr [rcx+20h]
vmovdqa     ymmword ptr [rdx],ymm0
vmovdqa     ymmword ptr [rdx+20h],ymm1

Die Google-Code zuvor von hplbsh geschrieben ist nicht sehr gut, weil sie alle 8 xmm verwenden registriert die Daten zu halten, bevor sie beginnen sie wieder zu schreiben, während er nicht benötigt wird - da wir nur zwei Ladeeinheiten haben und einen Speicher Einheit. Also nur zwei Register geben die besten Ergebnisse. Mit, dass viele Register in keiner Weise die Leistung verbessert.

Eine Speicherkopierroutine kann auch einige „fortgeschrittenen“ Techniken wie „Prefetch“ verwenden um den Prozessor zu instruieren Speicher in den Cache im Voraus und „nicht-temporal schreibt“ zu laden (wenn Sie sehr große Speicher chunks kopieren und nicht müssen die Daten aus dem Ausgangspuffer sofort lesen) sein, vs unaligned schreibt ausgerichtet, etc.

Moderne Prozessoren, seit 2013 veröffentlicht, wenn sie den ERMS-Bit in der CPUID haben, haben „enhanced rep MOVSB“ so genannten, so für große Speicherkopie, die „rep MOVSB“ verwendet werden kann - die Kopie wird sehr schnell, sogar schneller als mit den ymm Registern, und es wird richtig mit Cache arbeiten. Allerdings sind Anlaufkosten dieser Belehrung sehr hoch - etwa 35 Zyklen, so lohnt es sich nur auf große Speicherblöcke bis

.

Ich hoffe, es sollte jetzt einfacher für Sie, die beste Speicherkopierroutine für Ihren Fall erforderlich wählen oder schreiben.

Sie können sogar den Standard Memcpy / memmove, halten aber Ihre eigene spezielle largememcpy () für Ihre Bedürfnisse erhalten.

Je nachdem, was Sie versuchen zu tun ... wenn es groß genug Memcpy ist, und Sie sind nur dünn auf die Kopie schreiben, eine mmap mit MMAP_PRIVATE einen Copy-on-Write-Mapping denkbar könnte schneller erstellen sein .

auf Ihrer Plattform Je dort für bestimmte Anwendungsfälle sein kann wie, wenn Sie die Quelle und das Ziel kennen zu einer Cache-Zeile ausgerichtet sind und die Größe ist ein ganzes Vielfaches der Cache-Zeilengröße. Im Allgemeinen werden die meisten Compiler allerdings ziemlich optimal Code für Memcpy produzieren.

Ich bin mir nicht sicher, dass das Standard-Memcpy verwendet, ist immer die beste Option. Die meisten Memcpy Implementierungen ich angeschaut habe neigt dazu, die Daten zu Beginn, um zu versuchen und ausrichten und dann ausgerichtet Kopien machen. Wenn die Daten bereits ausgerichtet ist, oder ist recht klein, dann ist diese Zeit zu verschwenden.

Manchmal ist es von Vorteil Fach Wort Kopie, Halbwort Kopie, Byte Kopie Memcpy ist zu haben, solange es nicht zu negativ auf den Cache-Speicher einen Effekt hat.

Außerdem können Sie eine feinere Kontrolle über die tatsächliche Zuteilungsalgorithmus soll. In der Spieleindustrie ist es außerordentlich üblich, dass Menschen ihre eigenen Allozierungsroutinen zu schreiben, und zwar unabhängig davon, wie vielen Aufwand durch den Toolchain-Entwickler in erster Linie der Entwicklung es ausgegeben wurde. Die Spiele, die ich fast immer gesehen habe neigen Doug Lea Malloc verwenden.

obwohl Generell würden Sie Zeit mit dem Versuch Memcpy zu optimieren, da es werde kein Zweifel darüber bestehen, viel einfacher Bit-Code in Ihrer Anwendung zu beschleunigen.

verschwenden
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top