Homepage Wiki Forum Buy

GNUBLIN embedded GNU/Linux

Open source learning and training plattorm for embedded GNU / Linux
A projects from Hochschule Augsburg and embedded projects GmbH

Project homepage: http://www.gnublin.org
Wiki: http://wiki.gnublin.org
Aktuelle Zeit: Fr 22. Sep 2017, 00:56

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]




Ein neues Thema erstellen Auf das Thema antworten  [ 22 Beiträge ]  Gehe zu Seite 1, 2, 3  Nächste
Autor Nachricht
 Betreff des Beitrags: Wie schnell ist ein Gnublin?
BeitragVerfasst: Fr 1. Feb 2013, 00:09 
Offline

Registriert: Do 8. Nov 2012, 09:47
Beiträge: 93
Wohnort: Aachen
Für ein kleines Projekt hat mich interessiert, wie schnell so ein Gnublin denn ist - natürlich auch abhängig von der Programmiersprache. Da das eventuell von allgemeinem Interesse ist, poste ich meine Ergebnisse mal hier.
Wer mag kann noch ähnliche Tests machen und anhängen. und irgendwann wird vielleicht sogar eine Wiki-Seite draus.

Fangen wir mal gemütlich an:
Rechtecksignal an GPIO erzeugen per bash Skript ergibt eine Frequenz von 200 Hz oder benötigt 4,98s für 1000 mal Ein- und Ausschalten
Programmcode:
Code:
#!/bin/bash
GPIO=/sys/class/gpio
LedPort=3
Led=${GPIO}/gpio${LedPort}

function init_io ()
{ # prepare IO  ports
  echo ${LedPort} > ${GPIO}/export
  echo "out" > ${Led}/direction
}

function close_io ()
{
  if [ -e ${Led} ]; then echo ${LedPort} > ${GPIO}/unexport; fi
}

function led ()
{
  echo $1 > ${Led}/value
}

init_io
cnt=1000   # 4.98 s / 1000 = 200 Hz
while [ $cnt -gt 0 ]
do
  echo 1 > /sys/class/gpio/gpio3/value
  echo 0 > /sys/class/gpio/gpio3/value
  cnt=$(( cnt - 1 ))
done

#cnt=1000   # 8.97 s / 1000 = 111 Hz
#while [ $cnt -gt 0 ]
#do
#  led 1
#  led 0
#  cnt=$(( cnt - 1 ))
#done
close_io

Geht das schneller? Ja, ein klein wenig ... :o
Rechtecksignal an GPIO erzeugen per C mit "memory mapped IO" ergibt eine Frequenz von 740 kHz oder benötigt 2,7 s für 2Mio mal Ein- und Ausschalten.
Programmcode (Danke an Knallerbse für die Vorlage!):
Code:
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

/* LPC3131 UM chapter 15 */
#define IOCONFIG    0x13003000
#define FBLO_GPIO   0x1C0  /* GPIO functional block */

/* offset in GPIO functional block  */
#define MODE0       0x10 
#define MODE0_SET   0x14
#define MODE0_RESET 0x18
#define MODE1       0x20 
#define MODE1_SET   0x24
#define MODE1_RESET 0x28

/* !! Warning !!
 * GPIO4 (1 << 4) is a INPUT only. Writing a 1 to GPIO4 as output will crash the system!
 */
#define GPIO3   (1 << 3)
#define LED   GPIO3

void byebye(void);
char *mymem;

int main()
{
  int mem_fd;
  atexit(byebye);
  if ((mem_fd = open("/dev/mem", O_RDWR)) < 0) {
    printf("can't open /dev/mem \n");
    exit(-1);
  }
  mymem = mmap( 0
              , getpagesize()
              , PROT_READ|PROT_WRITE
              , MAP_SHARED
              , mem_fd
              , IOCONFIG );
  if (mymem == MAP_FAILED) {
    printf("mmap error %d\n", errno);
    exit(-1);
  }
  *(unsigned int *)(mymem + FBLO_GPIO + MODE1_SET) = LED;

//  int count = 1000000; // 1.37s -> 729 kHz
  int count = 2000000; // 2.7s -> 740 kHz

  while (--count) {
    *(unsigned int *)(mymem + FBLO_GPIO + MODE0_SET) = LED;
    *(unsigned int *)(mymem + FBLO_GPIO + MODE0_RESET) = LED;
  }
  return 0;
}

void byebye()
{
  /* when not explicitly given, munmap() will automatically be called on exit (see 'man munmap') */
  munmap(mymem, getpagesize());
}

Die übrigen Sprachen dürften alle zwischen diesen beiden Extremen liegen. Assembler ausgenommen, doch ist der für den Gnublin überhaupt verfügbar?


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: Wie schnell ist ein Gnublin?
BeitragVerfasst: Do 7. Feb 2013, 22:22 
Offline

Registriert: So 20. Jan 2013, 10:52
Beiträge: 37
Als größen Ordnung für das dazwischen mit dem C++ Progrämmchen und Linux like ca. 150Khz.
Assembler sollte doch der gcc können.

Code:
auto func = [&] ()
       {
         std::ofstream filePortValue ("/sys/class/gpio/GPIO11/value");

         for (;;)
         {
         // Port ausschalten
           filePortValue << "0" << std::flush;

         // Port einschalten
           filePortValue << "1" << std::flush;
         }

         filePortValue.close ();
       };

  std::thread t1 (func);


Grüße
Alexander


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: Wie schnell ist ein Gnublin?
BeitragVerfasst: Fr 8. Feb 2013, 00:27 
Offline

Registriert: Do 8. Nov 2012, 09:47
Beiträge: 93
Wohnort: Aachen
Im Prinzip müsste das ähnlich zu C über sysfs (/sys/class/gpio/*) sein. Da bin ich grade dran, aber eben noch nicht ganz fertig.

Zumindest bei memory mapped C sollte noch viel mehr drin sein. Der Prozessor läuft schließlich mit 180MHz. Wenn nun die IO Ports wirklich direkt per Pointer angesprochen würden, müsste das viel flotter gehen. Die Schleife übersetzt sich in sehr wenige Maschinenbefehle.

Könnte es sein, dass die Ports virtualisiert sind, oder die MMU heftig Zeit braucht?


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: Wie schnell ist ein Gnublin?
BeitragVerfasst: Fr 8. Feb 2013, 21:49 
Offline

Registriert: So 20. Jan 2013, 10:52
Beiträge: 37
Du hast da schon recht der Weg über das Filesystem kostet viel Zeit aber Memory Mapped IO ist halt schon eine richtige häßlichkeit. Es könnte hier aber helfen wenn man an der libstd++ oder der glibc vorbei die Kernelfunktionen direkt benutzt. Zumindest etwas schneller sollte das schon werden. Sauberer als Memory Mapped IO wäre dann ein Kernel Modul das die Zeitkritischen Teile der Signal Generierung übernimmt und die nötigen Daten aus dem Userspace geliefert bekommt.

Die C-Version wird auch nicht schneller sein. Ein weit verbreiteter Irrglaube das C++ soooviel langsamer als C ist.

Ich glaube nicht das der Kernel die Hardware Adressen nicht direkt anspricht. Es sind halt von der Anwendung bis zum CPU-Register eine ganze Reihe Funktions Aufrufe, Abfragen und der Taskswitch zwischen Userspace und Kernelspace die in der Summe einige Zeit kosten. Nicht zu vergessen das auch noch andere Tasks dazwischen kommen können die Zeit für sich beanspruchen.


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: Wie schnell ist ein Gnublin?
BeitragVerfasst: So 10. Feb 2013, 01:44 
Offline

Registriert: Do 8. Nov 2012, 09:47
Beiträge: 93
Wohnort: Aachen
So schlimm finde ich memory mapped IO nun auch wieder nicht. Das ist natürlich sehr an die Hardware gebunden, aber das ist man mit µController-Projekten idR doch sowieso.
Oder was ist sonst so hässlich daran?
Jedenfalls finde ich es viel schlimmer, wenn jedes Projekt/jeder Entwickler seine(n) eigenen Kernel(module) benötigt und damit nicht mal mehr auf dem gleichen System Programme austauschbar sind.

Dass C++ nicht langsamer sein muss als C, ist mir schon lange klar. Man muss sich halt etwas in den Kompiler rein denken.

Ich bin eigentlich davon ausgegangen, dass Memorymapping genau deshalb gemacht wird, damit man für zeitkritische Anwendungen schnell an die Register kommt, ohne durch unzählige Schichten durch zu müssen. Die Messwerte sprechen allerdings dagegen. Bei 740KHz auf einer 180MHz CPU wären das im Schnitt ganz grob abgerundet 200 Take pro Schleifendurchlauf. Der Integer-Zähler ist dabei schon durch das Abrunden mehr als berücksichtigt.
Das hieße dann, dass ein Zugriff über *(u_int)ptr 100 Takte braucht!??!

Andere Tasks sind es sehr wahrscheinlich nicht, denn sonst würden die Messwerte mehrerer Läufe breiter streuen.


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: Wie schnell ist ein Gnublin?
BeitragVerfasst: So 10. Feb 2013, 20:08 
Offline
Administrator

Registriert: Sa 7. Apr 2012, 09:18
Beiträge: 251
uns fehlt noch der High-Resolution Timer. Er sollte die Tage von benBrenson veröffentlicht werden. Aktuell blockiert der Scheduler alles schnelle.


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: Wie schnell ist ein Gnublin?
BeitragVerfasst: So 10. Feb 2013, 21:29 
Offline

Registriert: So 20. Jan 2013, 10:52
Beiträge: 37
Schwabix hat geschrieben:
Oder was ist sonst so hässlich daran?

Was stört sind die Sicherheitsprobleme und die nicht mehr saubere Trennung zwischen Kernelspace und Userspace.
Bei Debianpaketen kann man die installation eines Kernelmoduls automatisieren dann muss ein Anwender auch nicht mehr tun als halt Anwendung installieren. Mag sein das es Probleme gibt bei denen man nicht um Memory Mapped IO herum kommt aber so lange es nicht sein muss ist meine Empfehlung die Finger davon zu lassen.

Schwabix hat geschrieben:
Das hieße dann, dass ein Zugriff über *(u_int)ptr 100 Takte braucht!??!

Es läuft immer noch der Kernel und evtl. andere Usertasks die kosten Zeit. Das Dein Signal so konstant ist liegt vermutlich daran das die Systemlast bei Deinem Test konstant war. Bau Dir mal ein Programm das stark schwankende CPU Last verursacht. Dann sind die Schaltzeiten nicht mehr konstant.

sauterbe hat geschrieben:
uns fehlt noch der High-Resolution Timer

Ja ich weiß habe mich schon lautstark darüber beschwert ... :roll:
Im GIT Repo gibt es ja einen Kernel der das kann. Nur geht mit dem kein udev mehr. Zumindest habe ich das nicht hinbekommen. Nachdem ich dann in meiner Debian Installation die udev Scripte einfach mit "return 0" beedet habe konnte ich wieder booten. Ein nanosleep (1); liegt dann bei 300-350 us. Was schon mal sehr viel besser ist als 4 ms. Aber empfehlen kann man diese Kernel Version nicht die hat noch einige Probleme die in der anderen (die nicht hrtimer) schon gelöst sind.

Seid Ihr auch in Nürnberg?


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: Wie schnell ist ein Gnublin?
BeitragVerfasst: Mo 11. Feb 2013, 18:50 
Offline

Registriert: Di 19. Jun 2012, 15:20
Beiträge: 62
Die hrtimer sind mittlerweile Implementiert worden!

Lg
brenson


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: Wie schnell ist ein Gnublin?
BeitragVerfasst: Mi 13. Feb 2013, 10:12 
Offline

Registriert: Do 8. Nov 2012, 09:47
Beiträge: 93
Wohnort: Aachen
hmm, was benötigt man, um die zu testen? Derzeit habe ich einen Elektor-G (8M!) mit dem dort ausgelieferten ELDK.


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: Wie schnell ist ein Gnublin?
BeitragVerfasst: Mi 13. Feb 2013, 18:35 
Offline

Registriert: So 20. Jan 2013, 10:52
Beiträge: 37
Du kannst die Timer mit der Funktion nanosleep testen. Man darf aber nicht erwarten das die Funktion hält was sie verspricht. Nanosekunden erreichen nur CPUs die auch schnell genug sind. Der Gnublin erreichte bei mir ca. 300 oder 350 us.

Ein kurzes Beispiel könnte so aussehen.
Code:
struct timespec time;
time.tv_sev = 0;
time.tv_nsec = 1;

nanosleep (&time, NULL);


Ich habe das in eine Schleife gepackt und GPIO11 ein und wieder ausgeschaltet. Man kann dann per Oszi die Impulsdauer messen die bei mir leicht schwankt und ca. 350 us ist. Läßt man den nanosleep Aufruf weg dann ist die Impulsdauer ca. 5 us.


Nach oben
 Profil  
 
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 22 Beiträge ]  Gehe zu Seite 1, 2, 3  Nächste

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
cron
Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de