Hallo, folgende Frage habe ich: Ich habe ein (Frequenz)-Spektrum, das durch einen Detektor-Algorithmus laufen soll. In Hardware würde ich dafür einfach eine Art Schiebregister implementieren, es wird aber auf einen Mikrocontroller realisiert. Da wird ein aktueller Frequenzbin des Spektrums mit mehreren danebenliegenden Frequenz-Amplituden verglichen (und man gleitet über das gesamte Spektrum). Nun habe ich aber ein Array und zum Datenpunkt 0 (array[0]) müsste z.B. auch array[-16] und array[+16] herangezogen werden. array[<0] müsste mir den Wert 0 ausgeben, auch array[> Spektrum-Feldgröße] müsste mir 0 ausgeben. Soll ich nun ein erweitertes Feld indizieren mit der Feldgröße=[Spektrum-Feldgröße + 16 + 16] und die ersten 16 sowie die letzten 16 Feld-Elemente mit Null befüllen und dazwischen das ursprüngliche Feld mit den Spektralwerten einfügen oder gibt es dafür eine elegantere Lösung?
> Feldelemente außerhalb des Feldes
sind "Forbidden Territory".
Wenn du die Arrayberechnungen nicht sauber hinbekommst,
bau dir eine Funktion die das übernimmt und ausserhalb
eben 0 unt/oder einen Fehler zurückgibt.
Wie groß ist denn das Feld? 32 Byte mehr gegenüber mehrerer Vergleiche beim Zugriff ist zu Verschmerzen Bevor du jetzt noch neue Arrays erstellst oder kopierst, mach es gleich größer und fang ab Position 17 mit deine Messdaten an.
Daniel schrieb: > Nun habe ich aber ein Array und zum Datenpunkt 0 (array[0]) müsste z.B. > auch array[-16] und array[+16] herangezogen werden. > array[<0] müsste mir den Wert 0 ausgeben, auch array[> > Spektrum-Feldgröße] müsste mir 0 ausgeben.
1 | if (index < 0 || index > max_index) |
2 | return 0; |
3 | // weitere Berchnungen
|
4 | // ...
|
5 | return value; |
vielleicht einfach so?
Dirk B. schrieb: > Wie groß ist denn das Feld? 1024 x float32 MCU: Cortex-M4 > 32 Byte mehr gegenüber mehrerer Vergleiche beim Zugriff ist zu > Verschmerzen Sehe ich auch so. > Bevor du jetzt noch neue Arrays erstellst oder kopierst, mach es gleich > größer und fang ab Position 17 mit deine Messdaten an. Das finde ich auch gut. Ralf G. schrieb: > if (index < 0 || index > max_index) > return 0; > // weitere Berchnungen > // ... > return value; > > vielleicht einfach so? ich müsste vor jedem Feldzugriff eine Abfrage einbauen, das wird dann halt ein entsprechender Overhead. Danke!
Daniel R. schrieb: > ich müsste vor jedem Feldzugriff eine Abfrage einbauen, das wird dann > halt ein entsprechender Overhead. Nee. Da hast du schon einen prinzipiellen Fehler im Programmaufbau: Das Array sollte zu einem Modul (oder wie man's nennen will) gehören. Und nur dort werden Daten empfangen, verarbeitet, geschrieben. Wenn jetzt ein anderer Programmteil mit den Daten was anfangen will, dann holt der sich die Daten über eine Funktion aus diesem Modul (nennt man 'Datenkapselung'). Und somit kommt diese Bereichsprüfung nur einmal vor. Außerdem: wenn jetzt jemand auf die Idee kommt, außerhalb des Bereiches soll eine '-1' zurückgegeben werden, oder vielleicht ein Fehlercode, oder ... - dann fängst du wieder an dein ganzes Programm nach den Zugriffen zu durchsuchen!
Ralf G. schrieb: > Und somit kommt diese Bereichsprüfung nur einmal vor. Einmal im Code, aber bei jedem Zugriff. Macht das nicht schon std::vector
Daniel R. schrieb: > ich müsste vor jedem Feldzugriff eine Abfrage einbauen, das wird dann > halt ein entsprechender Overhead. Ein erweitertes Array ist auch ein Overhead. Das eine verursacht zusaetzliche Speicherzugriffe, das andere bedeutet zusatzliche Prozessorauslastung. Letzteres kann je nach Umstaenden schneller sein. Auf jeden Fall ist die Loesung mit der Routine, die die Grenzen beim Zugriff ueberprueft die robustere.
Der Landwirt nebenan ist nicht begeistert, wenn Fremde auf sein Feld zugreifen. Sein ausgestreckter Arm ist der Vektor, der auf Dein eigenes Feld zeigt.
Maxe schrieb: > Auf jeden Fall ist die Loesung mit der Routine, die die Grenzen beim > Zugriff ueberprueft die robustere Ja, aber ein Schieberegister ist als Rundspeicher angeordnet, der Wert vor Array[min] ist Array[max] und umgekehrt. Natürlich muss man auf Array-Anfang und Ende prüfen, aber die Werte werden ja kontinuierlich im Kreis herum reingeschrieben - das Array zu erweitern ist einfach nur Unsinn. Steht der Pointer auf 0, so ist der vorherige Wert der am Array-Ende, das ist ja auch genau der der zuvor geschrieben wurde, bevor der Schreibpointer auf 0 gesetzt wurde, weil der Array zu Ende ist. Ich hoffe das ist nicht zu kompliziert für einfach gestrickte Gemüter. Georg
georg schrieb: > Ich hoffe das ist nicht zu kompliziert für einfach gestrickte Gemüter. Wenn selbst Du es verstanden hast, dann bestimmt nicht!
Daniel schrieb: > Soll ich nun ein erweitertes Feld indizieren mit der > Feldgröße=[Spektrum-Feldgröße + 16 + 16] und die ersten 16 sowie die > letzten 16 Feld-Elemente mit Null befüllen und dazwischen das > ursprüngliche Feld mit den Spektralwerten einfügen oder gibt es dafür > eine elegantere Lösung? Die Technik mit den zusätzlichen Feldern nennt man auch "Sentinel", klassisch verwendet bei verlinkten Listen: https://de.wikipedia.org/wiki/Sentinel_(Programmierung) Man findet Sentinel aber auch in vielen anderen Bereichen und sie können Algorithmen und Implementierungen radikal vereinfachen und merklich beschleunigen. > 1024 x float32 > > MCU: Cortex-M4 Da sind 32 zusätzliche Werte ca. 3%. Ich steck nicht mehr so tief in Microcontrollerarchitekturen. Der M4 hat aber DSP-Kram und eine Pipeline. D.h. die Technik mit den Sentinel könnte bedeutend schneller sein (wenn andere Rahmenbedingungen passen), als irgendwelches if/then/else-Gedöns.
Wenn das Array genau 1024 Elemente hat, kann man auch einfach den Index mit 1023 aka 0x3ff 'verUNDen'.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.