www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ReadFile(.) - Zugriff auf die RS232 über Windows-API. Performance?


Autor: Alexander I. (daedalus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich greife mit Hilfe eines Workerthreads auf die serielle Schnittstelle 
zu. Dabei erfolgt die Kommunikation mit dem Hauptprogramm über jeweils 
eine separate queue<char>. Der Einfachheit halber habe ich mit ReadFile 
jedes Byte separat abgeholt und in die Queue eingefügt. Funktioniert 
auch, aber ich hab das Gefühl, die Performance ist da ganz schön 
bescheiden. Leider kann ich an keinem Pin wackeln und so am Oszi 
nachmessen, was da Phase ist.

Vielleicht kann mir jemand von euch eine Hausnummer nennen, wie lange so 
ein ReadFile-Aufruf durchschnittlich dauert und ob es besserer Stil ist, 
immer alle Bytes aus dem Rx-Puffer mit einem Aufruf zu lesen?

Autor: Volker Zabe (vza)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo
Dein 'Pin' ist der Performance-Monitor.
Deine Übertragung dauert : [Zeit] = [Anzahl-Bytes]/[baud]*10
Die Zehn komt von 8N1.

Sicherlich ist es Performanter ganze Blöcke zu lesen.
Aber du wirst es weder merken noch messen können.
Ich habe einen blockierenden Aufruf verwendet. Er kehrt bei mir erst 
zurück wenn entweder :
 - Bestimmte Anzahl Bytes angekommen sind.  oder
 - Ein bestimmtes Zeichen angekommen ist.   oder
 - Ein Timeout aufgetreten ist.

viel Spass beim Rechnen!

Autor: Alexander I. (daedalus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, deine Rechnung ist soweit schon klar. Ich habe aber die 
Befürchtung, dass der Löwenanteil vom Windows selbst verschlungen wird 
und ontop auf die reine Übertragungszeit kommt. Da hätte ich halt gerne 
eine Hausnummer wie lange so ein ReadFile(1 Datenbyte) im Durchschnitt 
dauert.

Vielen Dank soweit.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nochmal.
Es ist ziemlich egal, was du oder Windows in deinem Programm machst. 
Solange du nicht mutwillig Unmengen an Rechenzeit verbrutzelst 
natürlich. Dein zeitbestimmender Flaschenhals ist die eigentliche 
Übertragung an der seriellen Schnittstelle. Im Vergleich zu dem, was 
sich an dieser Schnittstelle abspielt, ist alles andere völlig 
unwichtig. Und wenn du zwischen dem Senden zweier Bytes 3 Millionen 
quadratische Gleichungen löst, wirst du den Unterschied nicht merken 
oder messen können.
Oder anders ausgedrückt: Ob die Küche 5 oder 10 Sekunden zur 
Bereitstellung eines Menütellers benötigt ist völlig uninteressant, wenn 
der Kellner 2 Minuten braucht um es zum Gast zu bringen. In dieser Zeit 
stellt die Küche den nächsten Teller auf jeden Fall her, egal ob sie 5 
oder 10 Sekunden dafür braucht.

Autor: Volker Zabe (vza)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
  LONGLONG  freq,start,stop,diff;
  double  time;

  HANDLE hProg = GetCurrentProcess();
  assert(hProg);
  assert(SetPriorityClass(hProg,REALTIME_PRIORITY_CLASS));

  hProg = GetCurrentThread();
  assert(hProg);
   assert(SetThreadPriority(hProg,THREAD_PRIORITY_HIGHEST));

  if(!QueryPerformanceFrequency((LARGE_INTEGER*)&freq))
  {
    printf("no PerformanceCounter,\n");
    exit (-2);
  }
  printf("freq is %I64u per sec.\n",freq);

  for(ByteData=0;ByteData<101;ByteData++)
  {
//    set = ByteData%6;
    set = ByteData;
    QueryPerformanceCounter((LARGE_INTEGER*)&start);
    Sleep(set);
    QueryPerformanceCounter((LARGE_INTEGER*)&stop);
    diff = stop - start;
    printf(" % 4u : ",set);
//    printf(" %I64u %I64u  %I64u ",start,stop,diff);
    time = diff;
    time /= freq;
//    printf(" %I64u %f ",diff,time);
    time *= 1000.0;
    printf(" %.3f ms",time);
    printf("\n");
  }
   fprintf(stderr,"\nHit any key.\n\n\n");
   getchar();
  exit(-1);

ich habe mal die Function sleep ausgemessen.
Ist das was du suchst?

Autor: Alexander I. (daedalus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe die Ursache für den schleichenden Workerthread gefunden. Die 
Fehlerursache war in der falschen bzw. nicht durchgeführten 
Konfiguration der Timeoutparameter begründet. Diese habe ich jetzt auf
COMMTIMEOUTS ctmo;
ctmo.ReadIntervalTimeout = MAXDWORD;
ctmo.ReadTotalTimeoutMultiplier = 0;
ctmo.ReadTotalTimeoutConstant = 0;
SetCommTimeouts(Device, &ctmo);

gestellt, damit ReadFile nicht im Timeout wartet (sofern keine Daten 
mehr kommen), sondern sofort zurückkehrt. Zusätzlich hab ich noch einen 
Fehler in meinen Synchronisations-Events gefunden und übertrage jetzt 
nicht jedes Byte einzeln sondern bis zu 256 pro Threaddurchlauf.

Das ganze flutscht jetzt um Größenordnungen besser. Die Abarbeitung 
eines "Kommunikationsablaufs" hat vorher gut 8-10 Sekunden gedauert. 
Nach der Überarbeitung <1 Sekunde.

Zwar war das hier nicht direkt die Problemlösung, hat mich jedoch auf 
den richtigen Lösungsweg gebracht. Vielen Dank soweit.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum soll das ReadFile denn zurückkommen wenn keine Daten empfangen 
wurde? Das ist ja sinn und zweck der Sache wenn du schon ein Extra 
Thread hast.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.