Forum: FPGA, VHDL & Co. Kleinsten / größten Wert finden


von Flo (Gast)


Lesenswert?

Hi,

ich bin gerade dabei, aus einer Menge von Werten den kleinsten bzw. 
größten Wert zu suchen. Das klappt eigentlich auch schon. Folgendermaßen 
sieht mein erster Versuch aus (PSEUDO-Code größter Wert):
1
variable tmp_max = 0
2
3
for A in erster_Wert to letzter_Wert loop
4
   if A > tmp_max then
5
      tmp_max = A
6
   end if
7
end loop

Das funktioniert soweit (in der Simulation!). Jedoch bin ich am 
überlegen, wie man das effizienter gestalten kann. Bspw. dass man etwas 
parallelisieren könnte. Nur habe ich noch keine gescheiten Ansatz 
gefunden.
Das Problem für mich ist, dass die Anzahl der Werte variabel ist (von 9 
- 81). Für 9 Werte ist es für mich z.B. noch vorstellbar, dass man 
parallel je zwei Werte nimmt und diese vergleicht. Dann nimmt man die 5 
Ergebnisse dieses Vergleichs und vergleicht wieder je zwei Werte usw... 
Das würde bei neun Werten 4 Takte benötigen, bis man das Ergebnis hat.
Ein andere Möglichkeit wäre die Werte zu sortieren, aber das nimmt 
wahrscheinlich mehr Zeit in Anspruch als die Suche nach dem kleinsten 
Wert.

Hat jemand evt. einen Tipp wie man die Suche nach dem größten bzw. 
kleinsten Wert auf einem FPGA umsetzen kann?

von faustian (Gast)


Lesenswert?

Ich sehe es mal gegeben dass eine von sich aus sortierte Datenhaltung 
nicht in Frage kommt?


Werte oder Teilmenge in Register geben, paarweise vergleichen, die 
ergebnisse der Vergleiche wieder in einen Registersatz halber Groesse 
geben, dort wieder paarweise....?

von Ras F. (rasfunk)


Lesenswert?

Ich weiß es nicht genau. Aber besser als O(n*log(n)) wird es wohl nicht 
gehen. Insofern bist Du mit Deinem binary Tree garnicht mal so schlecht.

Brauchst Du denn wirklich immer (d.h. jeden Takt) das Maximum/Minimum 
über den definierten Zeitraum? Oder reicht es, wenn Du nach z.B. 81 
Datensätzen das Maximum hast? In dem Fall könntest Du einfach die 
Variable gegen ein Register (Signal) tauschen und die Schleife weglassen 
und bist mit einem einzigen Komparator fertig. Das Register muss dann 
nach der entsprechenden Anzahl von Datensätzen zurückgesetzt werden.

von faustian (Gast)


Lesenswert?

Kommt auch auf den Wertebereich an - WAS sind das fuer Werte? Bei 4x4 
Bit oder so kaeme noch die GANZ brutale Methode (Bucketsort) in Frage...

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Du könntest auch ein Sortiernetz implementieren, das wäre dann auch 
Synthetisierbar.

von Flo (Gast)


Lesenswert?

Hallo allerseits,
vielen Dank für die Antworten!

Also, um etwas konkreter zu werden, es geht um Pixelwerte in einem 
Graubild (--> Wertebereich: 0 - 255).
Und pro Takt wird immer ein Bildbereich der Größe 3x3, 5x5, ... bis max 
9x9 betrachtet.
D.h. im "schlimmsten Fall" kommen wirklich pro Takt 81 Werte, von denen 
das min/max benötigt wird. Aber das min/max muss nicht nach einem Takt 
vorliegen. Das kann ruhig mit ein paar Takten Verzögerung geschehen.

> Du könntest auch ein Sortiernetz implementieren, das wäre dann auch 
Synthetisierbar.

Wäre eine Sortierung nicht Aufwendiger als nur min/max?

Wie es aussieht, läuft es wohl dann doch auf einen "Binary Tree" und 
paarweise Vergleichen raus.

von Flo F (Gast)


Lesenswert?

Wo siehst Du den paarweisen Vergleich?
Dein Loop im ersten Post ist bereits O(n), er schaut jeden Wert genau 1x 
an - und dass muss er wohl auch.

Zum paralleliseren bleibt Dir wie wohl in der Tat ein (binaerer) Baum, 
der aber im zeitlich optimalsten Fall dann auf unterster Eben 40 
Vergleiche gleichzeitig machen muss. Alternativ je nach Speicherlayout 
an Zeilen/Reihen parallelisieren & am Ende aggregieren.
Aber an der Gesamtzahl Operationen aendert das nichts (sie steigt 
sogar).

Gruss
Flo

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Flo schrieb:
>> Du könntest auch ein Sortiernetz implementieren, das wäre dann auch
> Synthetisierbar.
>
> Wäre eine Sortierung nicht Aufwendiger als nur min/max?
Jein.. Du brauchst ja keins was alle Werte sortiert, sondern nur eins 
was dir das größte Element nach oben sortiert. (Ein Pfeli repräsentiert 
ein Element was Zwei Werte der größe nach Vertauscht)
Das Sortiernetz würde dann so aussehen für 4 Werte:
1
a ------------^--- max
2
              |
3
b -------^--------
4
         |
5
c ---^------------
6
     |
7
d ----------------
Da gibt es natürlich jezt noch tolle Optimierungen aber die sind hier 
m.m nach nicht nötig. Nach einer initialen Latenz von 3 Takten kommt in 
jedem Takt ein neuer Maximalwert heraus da du aus jedem Schritt eine 
getaktete Stufe machen kannst, und da du eh einen Strom von Daten hast 
ist das doch optimal...

> Wie es aussieht, läuft es wohl dann doch auf einen "Binary Tree" und
> paarweise Vergleichen raus.
Geht auch als "Binärer Vergleicher" aber das funktioniert nur gut mit 
Zweierpotenzen:
1
a ---------------- 
2
      |        
3
b ---`´---^------- max
4
          |
5
c ---^------------
6
     |
7
d ----------------
Du brauchst trozdem drei Vergleicher, hast also keine Hardware gesparrt, 
das einzige ist das die Initiale Latenz der Pipeline einen Takt kürzer 
ist, und das ganze funktioniert nur mit 2er Potenzen.

von D. I. (Gast)


Lesenswert?

Läubi .. schrieb:

> Du brauchst trozdem drei Vergleicher, hast also keine Hardware gesparrt,
> das einzige ist das die Initiale Latenz der Pipeline einen Takt kürzer
> ist, und das ganze funktioniert nur mit 2er Potenzen.

Und falls man die nicht hat, kann man immer noch entsprechend mit 
Dummywerten auffüllen

von Flo (Gast)


Lesenswert?

Danke für die Anregungen und Ideen! Ich werde es mir mal durch den Kopf 
gehen lassen, welche Möglichkeit sich bei mir am einfachsten realisieren 
lässt.

Grüße
Flo

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
Noch kein Account? Hier anmelden.