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?
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!
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.
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.
1 | LONGLONG freq,start,stop,diff; |
2 | double time; |
3 | |
4 | HANDLE hProg = GetCurrentProcess(); |
5 | assert(hProg); |
6 | assert(SetPriorityClass(hProg,REALTIME_PRIORITY_CLASS)); |
7 | |
8 | hProg = GetCurrentThread(); |
9 | assert(hProg); |
10 | assert(SetThreadPriority(hProg,THREAD_PRIORITY_HIGHEST)); |
11 | |
12 | if(!QueryPerformanceFrequency((LARGE_INTEGER*)&freq)) |
13 | {
|
14 | printf("no PerformanceCounter,\n"); |
15 | exit (-2); |
16 | }
|
17 | printf("freq is %I64u per sec.\n",freq); |
18 | |
19 | for(ByteData=0;ByteData<101;ByteData++) |
20 | {
|
21 | // set = ByteData%6;
|
22 | set = ByteData; |
23 | QueryPerformanceCounter((LARGE_INTEGER*)&start); |
24 | Sleep(set); |
25 | QueryPerformanceCounter((LARGE_INTEGER*)&stop); |
26 | diff = stop - start; |
27 | printf(" % 4u : ",set); |
28 | // printf(" %I64u %I64u %I64u ",start,stop,diff);
|
29 | time = diff; |
30 | time /= freq; |
31 | // printf(" %I64u %f ",diff,time);
|
32 | time *= 1000.0; |
33 | printf(" %.3f ms",time); |
34 | printf("\n"); |
35 | }
|
36 | fprintf(stderr,"\nHit any key.\n\n\n"); |
37 | getchar(); |
38 | exit(-1); |
ich habe mal die Function sleep ausgemessen. Ist das was du suchst?
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
1 | COMMTIMEOUTS ctmo; |
2 | ctmo.ReadIntervalTimeout = MAXDWORD; |
3 | ctmo.ReadTotalTimeoutMultiplier = 0; |
4 | ctmo.ReadTotalTimeoutConstant = 0; |
5 | 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.
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.
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.