Ringspeicher



  • Ja du liegst da schon richtig.
    Du musst dann halt erst die 22 Bytes kopieren die von 0 - 21 reichen. (Arrays beginnen immer bei 0)
    Und dann eben noch die restlichen Bytes vom Ende des Arrays.
    Musst halt ein bissl rechnen.



  • Hey!!

    Hatte mir gedacht dass es da vielleicht irgend ein "fertiges" Programm ist dass sehr sehr schnell ist. Denn es müsste relativ schnell gehen diese Speicherung!!!

    black_devil



  • man könnte es mit einem index und modulo machen. du hast einen index, der auf das aktuelle element des arrays zeigt. um zum nächsten element zu kommen, berechnest den index mit folgender formel neu: index = (index + 1) % 1024. dadruch kreist der index immer zwischen 0 und 1023. willst du nun die letzten 50 werte auslesen, berechnest du index einfach umgekehrt: index = (index - 1) % 1024. dadurch geht der index wieder in die andere richtung. das machst du in einer schleife, die einfach 50 mal durchlaufen wird. wenn das fertig is, schreibst in index einfach 0 hinein und er beginnt wieder beim ersten array eintrag.

    was meinst?



  • hi

    mal kurtz nen vorschlag, du hast ja genau 1024 speichereinträge. damit könntest du nen counter mitlaufen lassen (ggf auch über den adressieren)
    1024 sind ja bekantlich 10 bits und geht von 0 - 1023. wenn du jetzt den counter immer mit ner maske 0x03ff und verknüpfst hast du immer den richtigen index. modulo rechnen kann wegfallen. das gleiche mit der subtraktion der letzten 50 werte. auch das sollte funktionieren. conter - 50 und dann mit maske verknüpfen das sollte dann die entsprechende position ergeben von der du aus anfangen musst zu kopieren. Und die entscheidung ob du am stück oder geteilt kopiren musst ist ja auch relativ einfach. ist start kleiner ende BlockCopy wen Ende kleiner start 2mal BlockCopy. und rumrechnen sollte man da dan auch nicht mehr, da sich die anderen start und endadressen ja schon vorgegeben sind.

    ps funktioniert mur mit rinpufferlängen von 2^n stellen

    gruss Termite



  • wenn er die bitmaske verwendet ist das auch modulo. er muss in restklasse Z1024 rechnen. wie er das implemenitert is egal.



  • "umgekehrt: index = (index - 1) % 1024"
    Na das will ich sehen wie das funktionieren soll^^



  • assembler schrieb:

    wenn er die bitmaske verwendet ist das auch modulo. er muss in restklasse Z1024 rechnen. wie er das implemenitert is egal.

    Bitmaske und Modulo ergeben bei negativen Zahlen eben nicht unbedingt das gleiche Ergebnis.

    Bei 1024 bräuchte man unbedingt ein 10bit System 😉

    Bei einem Integer mit 4 byte

    for(int i=0; i<20; i++) {
      index = (index - 1) % 1024;
      printf("%x ", index);
      }
    

    ergibt das

    ffffffff fffffffe fffffffd fffffffc fffffffb fffffffa ...

    Da 1024 mit 10 bit kodiert werden koennen muesste eine & Maske mit 0x3ff her.

    Das würde sinnvolle indexe ergeben

    for(int i=0; i<20; i++) {
      index = (index - 1) & 0x3ff;
      printf("%x ", index);
      }
    

    3ff 3fe 3fd 3fc 3fb 3fa 3f9 3f8



  • Ich habe so etwas selbst noch nicht implementiert, aber habe auch für ein Softsynth in der Richtung mal recherchiert gehabt. Es gibt da diverse Herangehensweisen und mit einer einfachen Schleife ist das alles nicht getan, so wie ich das raus bekommen habe.

    Vielleicht hilft das ja hier beim Einstieg in die Materie:
    http://en.wikipedia.org/wiki/Circular_buffer



  • Man kann sich an Adressen orientieren, und in Hexwerten denken (Bitbreiten und kleinste Adressiereinheiten beachten). 400H - 3CEH wäre dann der kritische Bereich. Zum Orientieren und Subtrahieren usw. wird dann mit logischen Operationen (OR, AND usw.) rumgemacht so gut es eben geht.
    Das ganze hängt aber ein wenig von der Hardware selber ab, mit der rumgemacht wird. 😉



  • CppNeuland schrieb:

    Vielleicht hilft das ja hier beim Einstieg in die Materie:
    http://en.wikipedia.org/wiki/Circular_buffer

    Konzepte sind ja prinzipiell klar, wenns nicht unbedingt Assembler sein soll
    reicht hier copy and paste.

    CppNeuland schrieb:

    mit einer einfachen Schleife ist das alles nicht getan, so wie ich das raus bekommen habe

    Wenn es nur einen Leser und einen Schreiber gibt (und man auf Synchronisation verzichtet)
    reichen einfache Schleifen zum Schreiben und Lesen eines gemeinsamen
    Bereichs wohl aus. Wenn man ungelesene Werte einfach überschreiben kann, benötigt
    man noch nicht mal eine Platzverwaltung.

    Mal ein paar Fragen:

    1. Muss es WIRKLICH Assembler sein ? Wenn ja Welcher Prozessor ?
    Der Performanceunterschied zu optimiertem C-Code ist (wenn überhaupt) minimal
    Man könnte auch den C-Compiler den Code generieren lassen ...

    2. Wenn es ein Betriebssystem mit Multitasking betrifft wäre eine parallele
    Auslegung zu empfehlen. Dann allerdings mit Synchronisation.
    -> Optimales Umfeld für Ringpuffer!


Anmelden zum Antworten