memcpy langsam auf iPad?

  • memcpy langsam auf iPad?

    Hi,

    ich habe einen ganz stinknormalen memcpy() mit eienr Größe von ca. 3MB in meiner App. Auf dem Simulator braucht dieser Erwartungsgemäß wenige Millisekunden, aber auf meinem iPad tatsächlich über 900ms, also fast 1 Sekunde. Gibt es da Probleme, sollte man eine andere Funktion nehmen oder ist das wirklich einfach so langsam?

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Thallius schrieb:

    Hi,

    ich habe einen ganz stinknormalen memcpy() mit eienr Größe von ca. 3MB in meiner App. Auf dem Simulator braucht dieser Erwartungsgemäß wenige Millisekunden, aber auf meinem iPad tatsächlich über 900ms, also fast 1 Sekunde. Gibt es da Probleme, sollte man eine andere Funktion nehmen oder ist das wirklich einfach so langsam?

    Gruß

    Claus

    memcpy oder wie?
  • Hm,

    also denkst Du , dass durch das VM Ich meinen 3MB Block nicht physikalisch an einer Adresse habe, sondern das Ganze durch die MMU gemappt wird und es deshalb so langsam ist ?

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Also es ist schon übel:

    Quellcode

    1. ULONG *imagedata= CGBitmapContextGetData (imageContextRef);
    2. myLog(@"memcpy...");
    3. for(int x=0;x<imageWidth*imageHeight;x++) // 1024x768
    4. {
    5. imagedata[x]=0;
    6. }
    7. myLog(@"done.");


    Dieser Code braucht auf einem iPad 1.5sekunden !(Wenn ich einen memset() nehme sind es nur noch die besagten 900ms)

    Wie bitte schön soll man denn da in Echtzeit Bildmanipulationen vornehmen ? Irgendwie muss das doch anders gehen. Ich kann mir nicht vorstellen das das nicht möglich sein soll.

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • 1. Sicher, dass Dein Timing genau genug ist? Logs sind ja gepuffert etc., wenn Du nur das nimmst, wage ich zu bezweifeln, dass Du genaue Messungen in so kleiner Größenordnung bekommst.

    2. Sieh zu, dass imagedata word-aligned ist, also die unteren drei bits der Adresse 0 sind (sollte eigentlich so sein, prüf das aber mal)

    3. Zum "Nullen" ist eventuell bzero effizienter.
    C++
  • Thallius schrieb:

    Hm,

    also denkst Du , dass durch das VM Ich meinen 3MB Block nicht physikalisch an einer Adresse habe, sondern das Ganze durch die MMU gemappt wird und es deshalb so langsam ist ?

    Gruß

    Claus

    Wieso sollte das die Sache langsamer machen?

    Copy-on-Write ist bei dir nicht sinnvoll?
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • zerm schrieb:

    1. Sicher, dass Dein Timing genau genug ist? Logs sind ja gepuffert etc., wenn Du nur das nimmst, wage ich zu bezweifeln, dass Du genaue Messungen in so kleiner Größenordnung bekommst.

    2. Sieh zu, dass imagedata word-aligned ist, also die unteren drei bits der Adresse 0 sind (sollte eigentlich so sein, prüf das aber mal)

    3. Zum "Nullen" ist eventuell bzero effizienter.


    Nein natürlich sind die Zeiten nicht genau, aber sie stimmen schon annähernd, denn das iPad macht wirklich über 1s dann nichts. Ich mache folgendes in einer Art InitEdit-Methode (schematisch):

    Quellcode

    1. // erzeuge einen ARGB Context
    2. self.imageContextRef=createARGBBitmapContext(self.image.size);
    3. // zeichne das Image rein. Das dauert schon recht lange, darum möchte ich das nur 1x machen und mir das Ergebnis merken
    4. CGContextDrawImage(imageContextRef, CGRectMake(0, 0, imageWidth,imageHeight),self.image.CGImage);
    5. // hole ich mir die rawdaten
    6. ULONG *imagedata= CGBitmapContextGetData (imageContextRef);
    7. // und merke sie mir als Backup
    8. srcData=malloc(imageWidth*imageHeight*4);
    9. memcpy(srcData, imagedata, imageWidth*imageHeight*4);


    hier dauert der memcpy knapp 50ms für ein 1024x768 Bild. Also vollkommen im Rahmen.

    Nun wird in einer anderen Methode nennen wir sie EditImage() zu einer anderen Zeit eben der Inhalt von srcData nach imagedata kopiert, imagedata geändert und angezeigt. Dort dauert dann der memcpy die besagte 1s. Ich nehme einfach mal an, dass da in der Zwischenzeit einer der Buffer weg gepaged wird und es deshalb so lange dauert. Aber kann man das pagen verbieten ?

    @Mac

    Ich nehme an Du meinst OpenGL ? Also ich muss die einzelnen Pixel des Image manipulieren. Kann ich das auch unter OpenGL oder CoreGrafics tun ? Also ich denke nicht das so etwas wie GetPixel() oder SetPixel() dann schneller wäre oder ?

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Mach doch bitte wirklich echte Timings. Das schliesst einfach Probleme und Fehler aus. NSLog kommt erst, wenn stdout geflushed wird.

    Ob Deine 3MiB jetzt wirklich raus-gepaged werden, wage ich auch mal zu bezweifeln. Aber schau mal, ob mlock(2) auch auf dem iOS unterstützt wird (sollte eigentlich, spricht nichts dagegen). Damit hälst Du die Seite im Speicher.
    C++
  • macmoonshine schrieb:

    gibt's OpenCL nicht auch unter iOS?

    Damit würde mich Apple echt mal beeindrucken. Ist es wahrscheinlich, dass Apple mich beeindruckt? Eher nicht.

    Thallius schrieb:

    ch nehme an Du meinst OpenGL ? Also ich muss die einzelnen Pixel des Image manipulieren. Kann ich das auch unter OpenGL oder CoreGrafics tun ? Also ich denke nicht das so etwas wie GetPixel() oder SetPixel() dann schneller wäre oder ?

    Du kannst einfach mehrere Pixel auf einmal (etwa in einem Shader) manipulieren. Ich weiss nicht genau, wie das auf den i-Geräten ausschaut, aber eventuell haben auch die dezidierten Graphikspeicher mit höherem Durchsatz.
    C++
  • Thallius schrieb:

    Ich nehme an Du meinst OpenGL ?

    de.wikipedia.org/wiki/OpenCL

    Thallius schrieb:

    lso ich muss die einzelnen Pixel des Image manipulieren. Kann ich das auch unter OpenGL oder CoreGrafics tun ? Also ich denke nicht das so etwas wie GetPixel() oder SetPixel() dann schneller wäre oder ?

    Wahrscheinlich wäre Core Image die richtige (Apple-) Technologie dafür. Die gibt's aber leider noch nicht auf dem Telefon...
    „Meine Komplikation hatte eine Komplikation.“
  • Wie genau möchtest du die Bilder verändern?

    Um deinen Code zu optimieren kannst du folgendes machen:
    1.L1, L2, L3 Cache - Optimierung.
    2.Du kannst dir die SEE - Einheiten zu nutzte machen.
    3.Du kannst schauen, ob die Daten im Speicher ausgerichtet sind (Was sowieso sein sollte und für SEE wichtig ist).
    4.Grafikkarte verwenden - OpenCL wird noch nicht unterstützt, wahrscheinlich auch aus dem Grund, da vieles schief gehen kann, schlechtes debugging und ein kompilieren zur Laufzeit wird durchgeführt.
    Stürzt das Programm ab, so befindet sich die Grafikarte in einem inkonsistenten Zustand - da hilft nur ein reboot.
    Wie Zerm schon sagte kannst du mithilfe von OpenGL 2.0 die Shadereinheiten verwenden.
    Inos ist ein Gott aus Gothic, dem Spiel.
  • Inos schrieb:

    Wie genau möchtest du die Bilder verändern?

    Um deinen Code zu optimieren kannst du folgendes machen:
    1.L1, L2, L3 Cache - Optimierung.
    2.Du kannst dir die SEE - Einheiten zu nutzte machen.
    3.Du kannst schauen, ob die Daten im Speicher ausgerichtet sind (Was sowieso sein sollte und für SEE wichtig ist).
    4.Grafikkarte verwenden - OpenCL wird noch nicht unterstützt, wahrscheinlich auch aus dem Grund, da vieles schief gehen kann, schlechtes debugging und ein kompilieren zur Laufzeit wird durchgeführt.
    Stürzt das Programm ab, so befindet sich die Grafikarte in einem inkonsistenten Zustand - da hilft nur ein reboot.
    Wie Zerm schon sagte kannst du mithilfe von OpenGL 2.0 die Shadereinheiten verwenden.

    ARMs haben kein L3, oder? Nichtmal unbedingt L2, aber keine Ahnung, wie das auf den iDevices ausschaut. Da ist sicherlich alles etwas anderes, gibt ja noch then THUMB-Mode etc, womit man Optimieren bzw. den Durchsatz erhöhen kann. Und SSE (SEE?) heisst dort wohl NEON. Gut, dass ich nicht ARM-optimieren muss, da hätte ich grad echt keine Lust zu :)

    Das bei OpenCL viel schiefgehen kann ist aber sicher nicht der Grund für die fehlende Unterstützung. Soweit ich mich erinnern kann, gibt es schon einige Prototypen (oder sogar Geräte auf dem Markt?), die OpenCL/CUDA unterstützen. Glaub mir, ich habe sooft schon OpenCL (oder auch CUDA) Kernel gecrashed aber dass ich rebooten musste war dann doch eher selten. Ich glaube nicht, dass das gross anders auf den iDevices sein sollte.

    Und wenn man ein Knoten im Hirn bekommen will, kann man auch ohne Shader mit OpenGL auf den älteren Geräten mehr oder minder brauchbare Bildverarbeitung betreiben. Es gibt ja wirklich Menschen, die finden die Register-Combiners schön. Naja, ich nicht :)
    C++
  • So,

    was ein verrückter Tag.

    Ich habe das ganze jetzt einfach noch einmal neu geschrieben und habe auf folgendem Weg ein brauchbares Ergebnis.

    Ich erzeuge einen ARGBContext, mache ein Draw hinein und merke ihn mir.

    Zum Anzeigen des Images erzeuge ich einen ARGBContext, lese die Srcdaten aus dem gemerkten Context, verändere sie wie gewünscht und schreibe sie in den Neuen. Dann mache ich daraus ein UIImage und zeige es an. Das Ganze dauert jetzt ca. 180ms. Also habe ich ca. 5-6 Bilder/s womit ich leben kann da es kein Echtzeit sein muss. Ausserdem ist es noch gar nicht optimiert. Ich denke das unter 100ms zu bekommen wäre sogar möglich.

    Komischerweise wird es sofort langsam, wenn ich den Zielcontext auch schon vorher erzeuge und mir merke. Da das Erzeugen des Contextes aber nur ein paar ms dauert kann ich damit leben ihn jedesmal anzulegen vorm Zeichnen. Komisch finde ich es trotzdem.

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • ARMs haben kein L3, oder? Nichtmal unbedingt L2, aber keine Ahnung, wie
    das auf den iDevices ausschaut. Da ist sicherlich alles etwas anderes,
    gibt ja noch then THUMB-Mode etc, womit man Optimieren bzw. den
    Durchsatz erhöhen kann. Und SSE (SEE?) heisst dort wohl NEON. Gut, dass
    ich nicht ARM-optimieren muss, da hätte ich grad echt keine Lust zu :)



    Das bei OpenCL viel schiefgehen kann ist aber sicher nicht der Grund für
    die fehlende Unterstützung. Soweit ich mich erinnern kann, gibt es
    schon einige Prototypen (oder sogar Geräte auf dem Markt?), die
    OpenCL/CUDA unterstützen. Glaub mir, ich habe sooft schon OpenCL (oder
    auch CUDA) Kernel gecrashed aber dass ich rebooten musste war dann doch
    eher selten. Ich glaube nicht, dass das gross anders auf den iDevices
    sein sollte.



    Und wenn man ein Knoten im Hirn bekommen will, kann man auch ohne Shader
    mit OpenGL auf den älteren Geräten mehr oder minder brauchbare
    Bildverarbeitung betreiben. Es gibt ja wirklich Menschen, die finden die
    Register-Combiners schön. Naja, ich nicht :)
    Klar meine SEE (SIMD), das es NEON auf dem ARM heißt wusste ich nicht.
    L1 - L2 habe einige (z.B. der ARM - Cortex A8), aber ARM - Prozessoren mit L3 habe ich noch nicht gesehen.
    Ist die GPGPU - Programmierung mit CUDA einfacher?
    Inos ist ein Gott aus Gothic, dem Spiel.