Gehts noch schneller ...?



  • Mich würde mal interresieren ob ihr eine schneller oder eleganter Lösung
    für mein Problem habt.

    Folgendes:
    Es gibt ein unsigned char Puffer in den eine Grafik in 8Bit Farben steckt.
    Dieser Puffer soll nach 16 oder 32 Bit Konvertiert werden.
    Nun gibt es eine Farbtabelle (Palette) die die RGB Werte enthält.

    Ich mache nun Folgendes ...

    nach 16Bit

    unsigned char _8BitPuffer[1000];
    unsigned short _16BitBuffer[1000];
    unsigned short _Pallette16Bit[256];
    
    for (int i=0;i<1000;i++) _16BitPuffer[i]=_Pallette16Bit[_8BitPuffer[i]];
    

    nach 32Bit

    unsigned char _8BitPuffer[1000];
    DWORD _32BitBuffer[1000];
    DWORD _Pallette32Bit[256];
    
    for (int i=0;i<1000;i++) _32BitPuffer[i]=_Pallette32Bit[_8BitPuffer[i]];
    

    Mich würde mal interresieren ob man da noch was Optimieren kann?
    Bin gespannt auf eure Komentare

    AndOne



  • Ja, benutze ++i statt i++ ! Schau mal hier:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-39454.html



  • MiP schrieb:

    Ja, benutze ++i statt i++ ! Schau mal hier:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-39454.html

    Spielt bei Built-Ins keine Rolle, aber wenn man sich Preincrement angewöhnt, dann benutzt man ihn auch automatisch bei anderen Typen.



  • Oh, muss ich zu meiner Schande gestehen das mit dem ++i kannt ich bisher garnicht.
    Werds mir mal anschauen.



  • @OP: Ich glaube nicht dass man da noch was rausholen kann.

    @MiP: Das ist jetzt aber nicht ernst gemeint???



  • Das einzige, was mir noch einfiele, wäre zu parallelisieren. Das geht in dem Beispiel recht gut. Allerdings wäre wohl bei einer so geringen Datenmenge (1000 Byte => 4000 Byte) der Aufwand zur Erstellung der Threads größer als der Gewinn an Schnelligkeit. Vielleicht solltest du es einfach mal messen.

    Gruß
    Don06



  • das mit den 1000 bytes war nur ein Beispiel, in der Praxis sind das dann so 157248
    Bytes. Das merkt man dann schon denk ich, das ganze muss 50mal in der sek passieren.



  • Je nach Anwendung ließe sich auch mmx, sse* oder so benutzen. Also keine Threads sondern direkte parallele Berechnung in der Hardware. Was das ganze natürlich nicht wirklich portabel machen würde. OpenMP würde die parallelisierung von Schleifen sehr einfach machen, aber es muss abgewägt werden, ob das was bringt (mehrere CPUs?).



  • welche IDE verwendest du? compilier das mal im release modes, dann müsste das machbar sein.



  • Vielleicht schneller:

    unsigned char _8BitPuffer[1000];
    unsigned short _16BitBuffer[1000];
    unsigned short _Pallette16Bit[256];
    
    unsigned char *8BitPtr = _8BitPuffer;
    unsigned char *16BitPtr = _16BitBuffer;
    
    for (int i=0;i<1000;i++) *(16BitPtr++) =_Pallette16Bit[*(8BitPtr++)];
    

    oder gar:

    unsigned char _8BitPuffer[1000];
    unsigned short _16BitBuffer[1000];
    unsigned short _Pallette16Bit[256];
    
    unsigned char *8BitPtr = _8BitPuffer;
    unsigned char *16BitPtr = _16BitBuffer;
    
    for (int i=0;i<500;i++){
      *(16BitPtr++) =_Pallette16Bit[*(8BitPtr++)];
      *(16BitPtr++) =_Pallette16Bit[*(8BitPtr++)];
    }
    

    Wobei die Schleife an sich wohl kaum Zeit verbrät.

    Oder Duff's Device:

    unsigned char _8BitPuffer[1000];
    unsigned short _16BitBuffer[1000];
    unsigned short _Pallette16Bit[256];
    
    unsigned char *8BitPtr = _8BitPuffer;
    unsigned char *16BitPtr = _16BitBuffer;
    
        int count = 1000;
    
        int n = (count + 7) / 8;
        switch (count % 8) {
        case 0: do { *(16BitPtr++) = _Pallette16Bit[*(8BitPtr++)];
        case 7:      *(16BitPtr++) = _Pallette16Bit[*(8BitPtr++)];
        case 6:      *(16BitPtr++) = _Pallette16Bit[*(8BitPtr++)];
        case 5:      *(16BitPtr++) = _Pallette16Bit[*(8BitPtr++)];
        case 4:      *(16BitPtr++) = _Pallette16Bit[*(8BitPtr++)];
        case 3:      *(16BitPtr++) = _Pallette16Bit[*(8BitPtr++)];
        case 2:      *(16BitPtr++) = _Pallette16Bit[*(8BitPtr++)];
        case 1:      *(16BitPtr++) = _Pallette16Bit[*(8BitPtr++)];
                   } while (--n > 0);
    




  • @Fellhuhn, werd mal nachher das ganze messen. Mal kucken obs damit wirklich
    schneller geht, meld mich dann mit den Ergebnissen.

    Thorsten


Anmelden zum Antworten