copy eveery second byte



  • Hallo ich möchte von nem byte array mit Bildaten jedes zweite Byte in ein neues Array kopieren. (YUV -> gray)

    memcpy kann mir ja nur das gesammte Array kopieren.
    und for schleife ist zu langsamm

    compiler ist gcc.
    ach so ja und sprache ist c++

    vielen dank schonmal
    Felix


  • Mod

    und for schleife ist zu langsamm

    Wut?

    unsigned char* resptr = zweitesarray;
    for( unsigned char* ptr = array; ptr < array + sizeof(array); ptr += 2 )
        *resptr++ = *ptr;
    

    Oder so ähnlich.

    ach so ja und sprache ist c++

    Das hoffe ich doch.



  • ok ein Denkfehler hab ich bei mir schonmal gefunden ich kann natürlich die 2er iteration im Schleifen kopf machen . Ich hatte das nochmal extra gemacht.;-)
    problem sehe ich aber sonst noch das ich bei jedem byte nen abgleich machen muss ob ich schon am ende bin.
    Ich hatte letztens was cooles gefunden
    http://en.wikipedia.org/wiki/Duff's_device
    das könnte ich ja auch mal probieren


  • Mod

    flexbex schrieb:

    Ich hatte letztens was cooles gefunden
    http://en.wikipedia.org/wiki/Duff's_device
    das könnte ich ja auch mal probieren

    Das erzeugt aber meiner Erfahrung nach heutzutage langsameren Code als eine naive Schleife. Probier's aber trotzdem mal aus, allein schon wegen dem Coolnessfaktor 🕶 .



  • Der Compiler sollte (hoffentlich) loop-unrolling selber versuchen, zumindest mit -O3.



  • flexbex schrieb:

    http://en.wikipedia.org/wiki/Duff's_device
    das könnte ich ja auch mal probieren

    Völlig falscher Optimierungs-Ansatz. Das können alle Compiler schon.

    Nehme deinen Code, paste ihn in http://gcc.godbolt.org/ und vergleiche mit oder ohne deine Mikrooptimierungen. Ist beides gleich.

    Was etwas bringt, ist das SSE3, insbesondere die PSHUFB Instruction.

    Ich bringe es aber nicht fertig, besseren Assemblercode als der Compiler zu schreiben, deshalb nimm einfach die einfachste Implementierung

    void everysecond(unsigned char *__restrict dest, unsigned char *__restrict src, size_t n)
    {
       for (; n--; src += 2)
        *dest++ = *src;
    }
    

    und kompiliere mit O3 -march=native.



  • danke schonmal für die Seite die ist ja super.
    Kannte ich noch nich. Werds mir ma anschauen



  • Habs jetzt so gemacht:

    for (i = 0; i < 2 * cropY * imgSizeX; i += 2 * imgSizeX) {
    			for (j=0; j < 2 * cropX; j += 2) {
    				*(targetBuffer++) = *(sourceBuffer + j + i);
     }
    }
    

    durch cropX und cropY wird das Bild noch beschnitten gleichzeitig



  • Die for-schleife könntest du noch mit OpenMP oder etwas vergleichhbaren parallelisieren, sodass mehrere Threads daran arbeiten.
    Auf jeden Fall wird das ganze ziemlich unübersichtlich und du solltest unbedingt gründlich und viel kommentieren. Gerade bei solchen hochoptimierten Ausschnitten ist es durchaus vernünftig, mehr Zeilen Kommentar zu haben als Code.


Log in to reply