Warum sind komplizierte Memcpy/Memsets überlegen?

Lesezeit: 6 Minuten

Benutzer-Avatar
Jakow Galka

Beim Debuggen bin ich häufig in die handgeschriebene Assembler-Implementierung von memcpy und memset eingestiegen. Diese werden normalerweise mithilfe von Streaming-Anweisungen implementiert, falls verfügbar, Schleife entrollt, Ausrichtung optimiert usw. Ich bin kürzlich auch darauf gestoßen ‘Fehler’ aufgrund von memcpy-Optimierung in glibc.

Die Frage ist: Warum können die Hardwarehersteller (Intel, AMD) den konkreten Fall nicht optimieren

rep stos

und

rep movs

als solche erkannt werden, und das tun am schnellsten möglichst ausfüllen und kopieren ihre eigenen die Architektur?

  • Cop-out-Antwort: Weil sie es einfach nicht tun, und infolgedessen schreibt niemand solchen Code, und deshalb gibt es keinen Grund für sie, dies zu tun … (Zyklus geht weiter)

    – Billy ONeal

    13. Januar 2012 um 23:50 Uhr


  • @BillyONeal: Ich glaube nicht. Für jedes neue Feature, das sie hinzufügen, gibt es noch keinen Code, der es verwendet.

    – Jakow Galka

    13. Januar 2012 um 23:57 Uhr

  • Ja, aber wenn eine neue Funktion hinzugefügt wird, wird sie hinzugefügt, um in dem einen oder anderen Bereich eine bessere Leistung zu zeigen. Eine Optimierung ist für CPU-Anbieter nicht sinnvoll, da Compiler keinen solchen Code ausgeben.

    – Billy ONeal

    14. Januar 2012 um 0:06 Uhr

  • @BillyONeal: Tatsächlich tun sie das. Die intrinsische Version von memcpy auf MSVC wird auf genau diesen Code erweitert.

    – Jakow Galka

    14. Januar 2012 um 0:09 Uhr

  • Intel Ivybridge und höher tun optimiert haben rep stos und rep movs. Intel nennt diese Unterstützung “Fast String” oder ERMSB (Enhanced Rep Movs/StosB). Weitere Informationen finden Sie im Optimierungshandbuch von Intel (verlinkt von stackoverflow.com/tags/x86/info). Dies ist immer noch eine gute Frage, warum frühere CPUs mikrocodierte Implementierungen von haben rep movs Take waren nicht so schnell wie eine SSE-Schleife, die 16 B-Ladevorgänge/Speichervorgänge ausführt.

    – Peter Cordes

    4. November 2015 um 22:18 Uhr

  • Gute Antwort. Oder wie ich es zusammenfassen würde: „Mach Dinge nicht in Hardware, wenn du sie genauso effizient in Software erledigen kannst“. Über das glibc-Ding: Torvalds ist hier eindeutig der Praktiker – den Benutzern ist es egal, warum etwas nicht funktioniert. Und das bezweifle ich irgendwie memmove hat einen spürbaren Leistungseinbruch im Vergleich zu memcpy in diesen Tagen .. müssen das testen.

    – Voo

    14. Januar 2012 um 0:41 Uhr


  • @ybungalobill: Ich habe einfach Kontext hinzugefügt, da Sie vielleicht die Geschichte von glibc kennen memcpyBesucher der Website möglicherweise nicht.

    – Dietrich Ep

    14. Januar 2012 um 0:45 Uhr

  • @Voo: Beachten Sie, dass Adobe das Flash-Plug-in repariert hat und dies heutzutage nur sehr wenige Leute zu stören scheint memcpy immer noch nicht memmove. Ich versuche nicht, Partei zu ergreifen.

    – Dietrich Ep

    14. Januar 2012 um 0:48 Uhr


  • @DietrichEpp: Vielleicht möchten Sie die Antwort umschreiben. Auf der einen Seite sagen Sie, dass ARM eine optimierte hinzufügt memcpy, andererseits, dass „der Trend in die entgegengesetzte Richtung geht“. Itanium ist schon lange tot, und die @PhiS-Antwort sagt, dass Intel diese Optimierung tatsächlich vor langer Zeit implementiert hat. Mir scheint, dass jeder diese CPU-Unterstützung für schnell akzeptiert hat memcpy/memset ist ein gewünschtes Feature, und das memcpy Implementierungen hinkten der Hardware hinterher, da die Auswahl des richtigen Pfads basierend auf der Laufzeitarchitektur zusätzlich komplex war.

    – Jakow Galka

    30. September 2021 um 14:01 Uhr

  • @YakovGalka: Ich habe das bereits in die Antwort aufgenommen und die Argumentation erläutert. Als Faustregel nehme ich Umschreibungen vor, sobald eine Antwort 100 positive Stimmen hat – wenn sie so viele Menschen erreicht, dann ist es die Mühe wert, sie umzuschreiben. Diese Antwort erreicht nicht so viele Menschen – nur 31 Gesamtstimmen (auf und ab) über 8 Jahre.

    – Dietrich Ep

    30. September 2021 um 17:35 Uhr

  • REP MOVS verwendet eine Cache-Protokollfunktion, die für regulären Code nicht verfügbar ist. Grundsätzlich wie SSE-Streaming-Speicher, aber auf eine Weise, die mit normalen Speicherordnungsregeln usw. kompatibel ist. // Der “große Aufwand für die Auswahl und Einrichtung der richtigen Methode” ist hauptsächlich auf das Fehlen der Mikrocode-Verzweigungsvorhersage zurückzuführen. Ich habe mir lange gewünscht, dass ich REP MOVS mit einer Hardware-Zustandsmaschine anstelle von Mikrocode implementiert hätte, was den Overhead vollständig hätte eliminieren können.

    – Krazy Glew

    4. September 2013 um 17:11 Uhr


  • @PeterCordes: Intel x86 hat seit dem Pentium Pro (P6) im Jahr 1996, den ich betreut habe, “schnelle Saiten”. Die schnellen P6-Strings nahmen REP MOVSB ​​und größer und implementierten sie mit 64-Bit-Mikrocode-Ladevorgängen und -Speichern und einem No-RFO-Cache-Protokoll. Anders als ERMSB in iVB verletzten sie die Speicherreihenfolge nicht.

    – Krazy Glew

    10. November 2015 um 14:47 Uhr

  • Umschreiben eines Kommentars, der einen Tippfehler mit automatischer Korrektur enthielt: @PeterCordes: Die große Schwäche beim Erstellen schneller Zeichenfolgen im Mikrocode waren (a) falsche Vorhersagen für Mikrocode-Zweige, und (b) der Mikrocode geriet mit jeder Generation aus der Stimmung und wurde langsamer und langsamer bis jemand dazu kam, es zu reparieren. Genauso wie eine Bibliotheks-Männer-Kopie verstimmt ist. Ich nehme an, dass es möglich ist, dass eine der verpassten Gelegenheiten darin bestand, 128-Bit-Ladevorgänge und -Speicher zu verwenden, sobald sie verfügbar wurden, und so weiter.

    – Krazy Glew

    10. November 2015 um 20:14 Uhr


  • Im Nachhinein hätte ich eine sich selbst optimierende Infrastruktur schreiben sollen, um einigermaßen guten Microcode auf jeder Generation zu bekommen. Aber das hätte nicht dazu beigetragen, neue, breitere Lasten und Lager zu nutzen, wenn sie verfügbar wurden. // Der Linux-Kernel scheint eine solche Autotuning-Infrastruktur zu haben, die beim Booten ausgeführt wird. // Insgesamt befürworte ich jedoch Hardware-Zustandsmaschinen, die reibungslos zwischen den Modi wechseln können, ohne dass es zu Fehlvorhersagen für Verzweigungen kommt. // Es ist fraglich, ob eine gute Mikrocode-Verzweigungsvorhersage dies verhindern würde.

    – Krazy Glew

    10. November 2015 um 20:19 Uhr

  • @KrazyGlew: Es scheint mir seltsam, dass “rep movs” kein ständiger Fokus der Hardwareoptimierung sein würde. Angesichts der Menge an anderer Logik auf einer modernen x86-CPU scheint die Menge, die erforderlich ist, um sicherzustellen, dass “rep movs” nie weit vom Optimum entfernt ist, ziemlich klein zu sein. Wenn Benutzercode, der ein schnelles Memcpy möchte, mit Logik beginnen muss, um den optimalen Ansatz auszuwählen, wird es für die Hardware schwierig sein, solche Tests vollständig wegzuoptimieren. Wenn Benutzercode einfach verwenden kann rep movs_ und lassen Sie die Hardware sich um den optimalen Ansatz kümmern, die Hardware muss solche Tests nicht wegoptimieren.

    – Superkatze

    6. September 2017 um 20:12 Uhr

  • Ich habe folgende Probleme mit dieser Antwort: “Diese Anweisungen sind allgemeingültig”, so ist das memcpy in der Bücherei. Es kann mit jeder Ausrichtung usw. arbeiten. “Bestimmtes Verhalten relativ zum Cache und / oder Status von Registern”. Die Semantik von “rep stos” ist viel einfacher als die auf SIMD basierende memcpy. Sie kennen die Nebenwirkungen, noch bevor Sie den Befehl ausgeführt haben, es ist nur so esi += ecx, edi += ecx, ecx = 0. Sonst ändert sich nichts, im Gegensatz zur SIMD-Version, wo man eigentlich fast alles auf der CPU nutzt.

    – Jakow Galka

    14. Januar 2012 um 0:29 Uhr

  • “Die spezialisierte Gedächtniskopie …” Ich spreche nicht über das Spezialisierte. “Die handgeschriebene Assemblierung kann die Bibliotheksimplementierung übertreffen …” was? Die Bibliotheksimplementierung ist das Handgeschriebene.

    – Jakow Galka

    14. Januar 2012 um 0:30 Uhr

  • @ybungalobill: Einige Leute schreiben ihre eigenen Mem-Copy-Funktionen und dann gibt es spezialisierte Bibliotheksimplementierungen. Mir war nicht klar, von welchen du sprichst. Ich werde meine Antwort präzisieren.

    – Guy Sirton

    14. Januar 2012 um 0:36 Uhr

  • Tunen Sie memcopy noch heute, und Ihre getunte Version kann auf jedem vorhandenen PC auf dem Markt bereitgestellt werden. Optimieren Sie REP MOVS, und es kann nur auf zukünftigen CPUs bereitgestellt werden. (Könnte Mikrocode-Patch verwenden, aber das wird hauptsächlich für Sicherheitslücken verwendet. Außerdem hat ucode-Patch Overhead.)

    – Krazy Glew

    4. September 2013 um 17:19 Uhr

  • Wenn Hardware/Firmware REP MOVS optimiert, profitiert jede App auf dem neuen Prozessor, die REP MOVS verwendet. Während jede Software, die Memcopy selbst optimiert hat, nicht von der optimierten Memcopy profitiert. Wenn eine solche Software verwendet “SIMD” lädt und speichert, idealerweise 512-Bit-volle Cache-Zeilenmemops, möglicherweise mit Vektormasken, dann kann sie von einer zukünftigen Hardware-Optimierung zu diesen profitieren.

    – Krazy Glew

    9. September 2017 um 14:16 Uhr

1365220cookie-checkWarum sind komplizierte Memcpy/Memsets überlegen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy