Speicherbereich mit nullen füllen



  • Hab mal ne Frage... (sonst würde ich ja kaum post 🤡 )
    Wie fülle ich mal schnellsten nen speicherbereich von 4-5k mit nullen?
    Mein erster versuch war ne einfache Schleife.. ist aber sch*** lahm..
    Mitlerweile bin auf folgendem stand:

    static char NULL_BUFFER[BUFFER_SIZE];
    // der buffer wird dann in der initialisierung mit nullen gefüllt
    
    // im prog
    static __inline void SetNull(char *bfr, int size)
    {
       _asm 
       {
            mov ecx, size
            mov esi, NULL_BUFFER
            mov edi, bfr
            rep movsb
       }
    }
    

    läuft ziehmlich schnell, wolle nur mal wissen ob womöglich einer von euch noch ne schnellere idee hat. Leider habe ich nicht viel Ahnung von MXX, SEE ect. funktion.. womöglich gibts da ja noch was.

    danke schon mal 🙂



  • rep stosd



  • thx!
    Werde es gleich mal testen 🙂 🙂



  • auf der AMD seite ist ein paper in dem sie viele verschiedene möglichkeiten den buffer zu füllen bzw. zu kopieren demonstrieren

    dabei gehen die auf die einzelnen caches/rambereiche ein usw.

    ist schon länger her dass ich das da las, hat was mit mmx zu tun gehabt.

    rapso->greets();



  • Wie dem auch sei, grundsaetzlich kann man noch sagen, dass die 32Bit Stringcodes (stosd) am schnellsten arbeiten, wenn man sie auf durch 4 teilbare Addressen loslaesst.



  • Nobuo T schrieb:

    Wie dem auch sei, grundsaetzlich kann man noch sagen, dass die 32Bit Stringcodes (stosd) am schnellsten arbeiten, wenn man sie auf durch 4 teilbare Addressen loslaesst.

    ???
    versteh ich da was falsch oder kann denn das nen Speedgewinn bringen:

    NULL_BUFFER_off = new char[BUFFER_SIZE+4);
    NULL_BUFFER = NULL_BUFFER_off;
    while(NULL_BUFFER%4)
      NULL_BUFFER++;
    
    _workBuffer_off = new char[BUFFER_SIZE+4);
    _workBuffer = _workBuffer_off;
    while(_workBuffe%4)
      _workBuffer++;
    

    mit den offsets mache ich nix mehr, die bleiben nur damit später alles wieder freigeben kann.. ich abreite jetzt mit der nächten Adress im Speichblock die durch 4 Teilbar ist.
    Hab ich das jetzt ganz verstanden, oder kann ich das so einbauen?



  • Im Prinzip ist das richtig was du daq schreibst, ich würde aber ganz stark davon ausgehen, dass jeder aktuelle Compiler das automatisch auf 4 aligned. In dem Fall verbraucht dein Check mehr Zeit 😉

    Check einfach mal aus, welche Adressen dir new gibt, wenn die sich ständig durch 4 teilen lassen, dannwürde ihc den extracode nicht nehmen, neben der Überflüssigkeit fördert das nämlich nicht die Lesbarkeit.



  • das würde sowieso in die initialiesrung kommen.. da kann daueren so lagen sie will.. wichtig ist nur der code der arbeiten muss schnell ist 🤡



  • am schnellsten sind MMX-mov befehle laut AMD 😕

    naja in dem paper sind die für copy und nicht 'nur' zum füllen von speicher, aber trotzdem vielleicht nen vesuch wert:

    http://cdrom.amd.com/devconn/events/gdc_2002_amd.pdf

    rapso->greets();



  • WOW! in den pdf stehen ein paar interessante dinge :))



  • sag isch doch 😃

    die erbauerfirmen haben die bestern sourcen für sowat :D:D:D
    woher nur? 🕶

    rapso->greets();



  • Irgendwie ist die Seite passwort geschützt. 🙄 🙄



  • war heute mittag irgendwie noch nicht
    *wundertsich*

    rapso->greets();



  • es gibt nen guten trick für sowas:

    ...
    mov ecx,size   ; lade die grösse
    shr ecx,1      ; teile grösse durch 2, falls size ungerade ist cf = 1
    rep stosw      ; schreibe die worte
    adc ecx,0      ; addiere das carryflag
    rep stosb          ; falls size ungerade war, schreibe noch ein byte
    

    eigentlich müsste auch das hier für 32bit klappen, habs noch nicth ausprobiert

    ...
    mov ecx,size   ; lade die grösse
    shr ecx,1      ; teile grösse durch 2, falls size ungerade ist cf = 1
    pushf          ; flags  sichern
    shr ecx,1      ; nochmal teilen gucken ob gerade anzahl von worten da ist
    rep stosd      ; schreibe die doppelworte
    adc ecx,0      ; addiere das carryflag
    rep stosw      ; falls size ungerade war, schreibe noch ein wort
    popf           ; flags nochmal laden
    adc ecx,0      ; wenn byteanzahl ungerade war
    rep stosb      ; dann schreibe noch ein byte
    

    könnte fehlerhaft sein, ist immerhin schon spät muss in heia ...


Anmelden zum Antworten