Guten Morgen werte Kollegen, Momentan bin ich dabei mich etwas näher mit der PC-Programmierung zu beschäfitgen, vorrangig in C. Bisher war ich nur auf dem Mikrocontroller - Embedded - Bereich tätig, mit allen Vorzügen: einfaches Debuggen und analysieren von z.B. Timings mittels Pin-Toggeln etc. Nun bin ich an einem Punkt angekommen, wo ich mal ein par Hinweise und Tips benötigen könnte (ich zähle auf euch :D): Der Mikrocontroller sendet ADC-Daten (105 KSp/s, 24-Bit/32-Bit)per UDP an meinen PC (Ist ein 24-Bit ADC (ADS1271), dessen Daten auf 32-Bit erweitert werden). Diese werden erst in einem Array gespeichert (Umwandlung in 32-Bit-Datentyp) und anschließend zum loggen in einer Datei abgelegt. (Es werden immer 4096 Byte = 1024 Werte in 4 UDP-Paketen empfangen und dann bearbeitet). Das Empfangen der Daten dauert momentan ca. 10ms = 1000Werte. Somit erhalte ich ca. 400KByte/s an Daten die auch alle fehlerfrei empfangen werden und auch in der Datei richtig abgelegt werden. Problem: Diese Daten sollen nun mit der FFTW-Bibliothek analysiert werden. Das Einbinden und benutzen der FFTW-Lib ist kein Problem und funktioniert auch ohne Probleme. Jedoch habe ich keine Ahnung wie lange der PC braucht um eine FFT eines Datensatzes (1024 Byte) auszuführen. Das Programm folgt momentan einem linearen Fluss, weshalb ich etwas Bedenken habe, dass Daten verloren gehen, während die FFT ausgeführt wird. Wie erreiche ich also am besten, dass die Daten per UDP gleichzeitig empfangen werden und verarbeitet werden? Dabei kann ich durchaus einen kleinen zeitlichen Versatz in Kauf nehmen nach dem Schema: 1. Fülle Buffer1 mit Daten die empfangen werden (im Hintergrund) und bearbeite die Daten in Buffer2 währenddessen. 2. Fülle Buffer2 mit Daten die empfangen werden (im Hintergrund) und bearbeite die Daten in Buffer1.... - Wie lautet hierzu das richtige Stichwort? - Bin ich mit Threading richtig beraten? - Wie kann ich genaue Timings am PC messen? Habe keinen Prallel-Port, nur USB, Ethernet... PC-System ist ein UBUNTU, Compiler GCC. Mit Dank und Grüßen im Vorraus, Tueftler
Aus dem Bauch raus würde ich die beiden Funktionen in eigenständigen Prozessen realisieren: -UDP Empfang ganz einfach mit nc/netcat, in eine pipe reinschaufeln -Analyse/Visualisierung mit deinem C Programm nach Wahl Etwas kritisch könnte die Puffergrösse der pipe sein, auf meiner Kiste ist die nur wenige KB (ulimit -a). Die etwas zu Vergrössern schadet sicher nix, ansonsten wird der schreibende Prozess (nc) blockieren, bis wieder Platz frei ist.
Tueftler schrieb: > Das Empfangen der Daten dauert momentan ca. 10ms = 1000Werte. > > Somit erhalte ich ca. 400KByte/s an Daten die auch alle fehlerfrei > empfangen werden und auch in der Datei richtig abgelegt werden. > > Problem: > Diese Daten sollen nun mit der FFTW-Bibliothek analysiert werden. > Das Einbinden und benutzen der FFTW-Lib ist kein Problem und > funktioniert auch ohne Probleme. > Jedoch habe ich keine Ahnung wie lange der PC braucht um eine FFT eines > Datensatzes (1024 Byte) auszuführen. Miss es einfach aus. Auch auf einem PC gibt es sowas wie einen Clock-Tick, den man abfragen kann. Goggle mal nach clock() Würde mich aber wundern, wenn das auf einem heutigen PC 10ms dauern würde. > Wie erreiche ich also am besten, dass die Daten per UDP gleichzeitig > empfangen werden und verarbeitet werden? Ehe du dich da jetzt in Experimente mit Multithreading einlässt, miss doch erst mal aus, ob du überhaupt ein Problem hast, das gelöst werden muss. Der Ethernet Stack empfängt die Daten ja sowieso schon parallel zu deinem Programm.
Tueftler schrieb: > Diese werden erst in einem Array gespeichert (Umwandlung in > 32-Bit-Datentyp) und anschließend zum loggen in einer Datei abgelegt. > (Es werden immer 4096 Byte = 1024 Werte in 4 UDP-Paketen empfangen und > dann bearbeitet). > Das Empfangen der Daten dauert momentan ca. 10ms = 1000Werte. Hast Du daran gedacht, das UDP Pakete auch mal verloren gehen können und Du dich um diesen Fehlerfall in deiner Software selbst kümmern must? Wenn möglich würde ich eher TCP verwenden, wobei man das auch später noch ändern kann. > Somit erhalte ich ca. 400KByte/s an Daten die auch alle fehlerfrei > empfangen werden und auch in der Datei richtig abgelegt werden. > > Problem: > Diese Daten sollen nun mit der FFTW-Bibliothek analysiert werden. > Das Einbinden und benutzen der FFTW-Lib ist kein Problem und > funktioniert auch ohne Probleme. > Jedoch habe ich keine Ahnung wie lange der PC braucht um eine FFT eines > Datensatzes (1024 Byte) auszuführen. > Das Programm folgt momentan einem linearen Fluss, weshalb ich etwas > Bedenken habe, dass Daten verloren gehen, während die FFT ausgeführt > wird. Der Linux Kernel wird eine gewisse Menge an Daten Puffern bevor er anfängt eingehende UDP Pakete zu verwerfen. Wieviel das ist kann ich jedoch nicht genau sagen. Immer dann wenn dein PC genötigt wird die Auslagerungspartition zu benutzen könnte es schwierig werden. Auch dieses Problem würde durch Verwendung von TCP behoben > Wie erreiche ich also am besten, dass die Daten per UDP gleichzeitig > empfangen werden und verarbeitet werden? > Dabei kann ich durchaus einen kleinen zeitlichen Versatz in Kauf nehmen > nach dem Schema: > 1. Fülle Buffer1 mit Daten die empfangen werden (im Hintergrund) und > bearbeite die Daten in Buffer2 währenddessen. > 2. Fülle Buffer2 mit Daten die empfangen werden (im Hintergrund) und > bearbeite die Daten in Buffer1.... > > - Wie lautet hierzu das richtige Stichwort? > - Bin ich mit Threading richtig beraten? > - Wie kann ich genaue Timings am PC messen? > Habe keinen Prallel-Port, nur USB, Ethernet... Ja, Multithreading ist dazu ein guter Ansatz. Du möchtest einen Ringpuffer verwenden. Normalerweise sollte aber die Rechenleistung locker ausreichen um das linear abzuarbeiten - auch hier, TCP hilft Dir. Um die Timings in dem Programm zu bestimmen kannst Du gprof benutzen. Einführung z.B. hier: http://www.linuxfocus.org/Deutsch/March2005/article371.shtml. Mit den richtigen Optionen kann man Timings auch für jede einzelne Programmzeile bestimmen. Denke aber daran, das ein PC kein deterministisches System wie ein Mikrocontroller ist. Die Timings können sich von Aufruf zu Aufruf ändern und hängen von zig Einflüssen ab, u.a.: - aktive Programme - Netzwerkverkehr - Nutzerinteraktion Daher, nimm TCP und Du hast es viel einfacher.
Hallo, herzlichen Dank für eure zahlreichen Antworten! Inzwischen läuft die Sache recht gut! Zum Glück ohne weiteres Threading. Bin @Tom: Tom M. schrieb: > -UDP Empfang ganz einfach mit nc/netcat, in eine pipe reinschaufeln > -Analyse/Visualisierung mit deinem C Programm nach Wahl > > Etwas kritisch könnte die Puffergrösse der pipe sein, auf meiner Kiste > ist die nur wenige KB (ulimit -a). Die etwas zu Vergrössern schadet > sicher nix, ansonsten wird der schreibende Prozess (nc) blockieren, bis > wieder Platz frei ist. Habe anfangs auch mit NetCat experimentiert, als ich auf dem Mikrocontroller den LwIP-Stack in Betrieb genommen habe. Verwundert war ich darüber, dass immer maximal 1024 Byte angekommen sind, egal wieviele ich per UDP gesendet habe... und par tout keinen Fehler in meinem MC-Programm finden konnte. Da hat NC anscheinend einen Bug (siehe auch Internet). Von daher war ich mit NC erstmal bedient. @Karl: Karl Heinz Buchegger schrieb: > Miss es einfach aus. > Auch auf einem PC gibt es sowas wie einen Clock-Tick, den man abfragen > kann. > Goggle mal nach clock() > > Würde mich aber wundern, wenn das auf einem heutigen PC 10ms dauern > würde. Mit clock() hats leider nicht funktioniert, evtl. hat mein System-Timer eine zu geringe Auflösung?! Mit clock_gettime() funktioniert es und es werden sogar Nanosekunden ausgegeben... (Wie genau das wohl ist....?!) http://linux.die.net/man/3/clock_gettime Habe dann die Zeitfresser identifiziert und wandle nun nur int32_t in strings um und keine float um die Daten zu loggen. Den größten Einfluss hatte aber immer noch die Optimierung, nun auf 3 gesetzt. Somit benötigt die FFT über 4096 (rein Rellwertige Float-)Datenpunkte zwischen 70...200 Micro-Sekunden. @Andreas: Andreas Messer schrieb: > Hast Du daran gedacht, das UDP Pakete auch mal verloren gehen können und > Du dich um diesen Fehlerfall in deiner Software selbst kümmern must? > Wenn möglich würde ich eher TCP verwenden, wobei man das auch später > noch ändern kann. Habe mich gerade für UDP entschieden, da es einen geringeren Overhead hat und damit vermutlich auch schneller ist?! Momentan ist der MC mit dem PC über einen Router verbunden, an dem nichts weiter hängt, von daher hoffe ich, dass da nichts verloren geht, werde aber in Zukunft vielleicht noch einen Index mitschicken, der es dann ermöglicht die Daten auf Konsistenz zu prüfen. Vielen Dankf für den Link, Sieht sehr interessant aus, werde ich gleich mal probieren, Profiling-Daten zu erstellen um zu sehen, wo sich das Programm die meiste Zeit aufhält. (Vermutlich in der UDP-Empfangsroutine, wo erstmal 16 Pakete zu je 1024Byte gesammelt werden). So Long, Vielen Dank, Tueftler
Ich wuerde mit Integern arbeiten, nicht mit float und auch nicht mit strings. UDP ist das Mittel der Wahl wenn man ein verlorenses Packet verschmerzen kann, wenn Geschwindigkeit wichtiger ist. zB Bild und Ton werden als UDP uebertragen. TCP ist das mittel der Wahl wenn alles sicher ankommen muss, zb bei eibem filetransfer.
Hallo, falls du Multi-Threading und/oder grafische Oberfläche programmieren möchtest könntest PureBasic benutzen. http://www.purebasic.com/german/index.php Die Sprache hat nur minimale Geschwindigkeitseinbusen gegenüber gutem C Code und für Multithreading schreibt man eine ganz normale Funktion und führt sie mit einer Befehlszeile lediglich asynchron zum Hauptprogramm aus. Es kann auch sehr einfach auf C - Bibliotheken zugegriffen werden. Die Hilfe ist auch außergewöhnlich gut (in Deutsch, Englisch und Französisch vorhanden) mit sehr vielen querverweisen zu hilfreichen Befehlen. Der Aufbau ist sehr stark mit C verwandt. Ja, ich weiß es ist eine kostenpflichtige Sprache, allerdings halten sich die Kosten mit 80€ in Grenzen und die Lizenzbedingungen sind traumhaft. Zudem ist sie nahezu Plattformunabhängig (kann auf Windows/Linux/Mac kompiliert werden). Gruß Kai
http://www.fftw.org/speed/ http://www.fftw.org/speed/Pentium3-1.266GHz/ mflops = 5 N log2(N) / (time for one FFT in microseconds) ~10 us für eine 256 Punkt FFT auf dem Pentium3...
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.