Benötige Codeerklärung char <--> int



  • Guten Tag,

    es geht um Bildpixel, ich lese dazu gerade ein Buch. Die Pixel werden als Chars gespeichert. Nun heißt es aber, dass die Zugriffe auf Chars nicht gerade schnell seien, daher solle man Int Variablen nehmen, da der Speicherzugriff auf diese schneller geschehen.

    Nun steht folgende Codezeilen mehr oder weniger isoliert im Raum:

    const int nWords = width * heigth / 4;
    const int nValue = g | (g<<8) | (g<<16) | (g<<24): //Hier kapier ich garnicht was passiert
    int* output = (unsigned char *)pixels;
    for(int i=0;i<nWords;i++)
    output[i] = nValue
    

    Vorher steht noch, dass ein Char ein Byte habe und ein Int 4 Byte (daher wohl die Division durch 4).

    Allerdings haperts doch recht arg am Verständnis bei mir.

    DANKE


  • Mod

    Das sind Bitverschiebeoperatoren. So wie sie dort verwendet werden, macht das aber keinen Sinn. Alle Bytes von nValue werden auf den Wert des Bytes g gesetzt.



  • Genau das ist aber das Ziel. Setzung aller Pixel auf einen Wert g. Muss mir dann wohl mal durchlesen was eine "Bitverschiebung" genau ist und wie sie funktioniert um das verstehen zu können.

    Danke


  • Mod

    SchwanAL schrieb:

    Genau das ist aber das Ziel. Setzung aller Pixel auf einen Wert g.

    Warum dann nicht das gute alte memset?



  • SeppJ schrieb:

    Das sind Bitverschiebeoperatoren. So wie sie dort verwendet werden, macht das aber keinen Sinn. Alle Bytes von nValue werden auf den Wert des Bytes g gesetzt.

    So machst du z.B. aus einem farbigen Bild ein Graustufenbild, das nur einen der Kanäle (z.B. Grün) darstellt. Kann also durchaus Sinn machen. In so einem Fall würde man aber der Alpha-Kanal in Ruhe lassen...



  • Sagt mir: g<<16:

    "Schieb mir das Byte "g" um 2 Byte (=16 Bit) nach links?"



  • SchwanAL schrieb:

    Sagt mir: g<<16:

    "Schieb mir das Byte "g" um 2 Byte (=16 Bit) nach links?"

    Richtig. 0x00a5<<8 ergibt also 0xa500.

    EDIT: Das bitweise Oder ist aber klar?



  • Ja, das ist mir klar. Dadurch dass nur "0"er vorran gestellt werden bekomm ich halt in dem Byte vorher wieder mein "g".

    Danke!



  • p.s.: Gruß nach Aiur 🙂



  • SeppJ schrieb:

    SchwanAL schrieb:

    Genau das ist aber das Ziel. Setzung aller Pixel auf einen Wert g.

    Warum dann nicht das gute alte memset?

    Langsamer? memset bedeutet Speicherzugriffe, im Gegensatz dazu sind diese Verschiebungen reine Arithmetik. </spekulation>



  • Achso, gerade erst gelesen (memset)

    Ich weiß nicht die Hintergründe, das Buch geht aber davon aus dass arithmetisch-logische Operationen um ein Vielfaches schneller sind als Speicherzugriffe.


  • Mod

    Bashar schrieb:

    SeppJ schrieb:

    SchwanAL schrieb:

    Genau das ist aber das Ziel. Setzung aller Pixel auf einen Wert g.

    Warum dann nicht das gute alte memset?

    Langsamer? memset bedeutet Speicherzugriffe, im Gegensatz dazu sind diese Verschiebungen reine Arithmetik. </spekulation>

    Memset ist ja nicht dumm. Intern darf das allerlei böse Sachen machen die man in Standard-C gar nicht kann. Und das optimal für die Zielarchitektur.



  • Stimmt, hätte ich nicht in der Form erwartet. Der gcc macht bei memset(&i, c, sizeof(i)) sogar nur zwei shifts, einmal um 8, darauf addiert er nochmal das Original, schiebt dann alles um 16 und addiert wieder. 👍

    edit: Und natürlich alles in Registern.



  • dennoch sollte man eher dem std::fill oder dem std::fill_n den vorzug gegenüber memset() geben 😉


Anmelden zum Antworten