Forum: PC Hard- und Software schneller I/O zugriff auf x86-PC


von Martin L. (sbond)


Lesenswert?

Hallo zusammen,

kennt jemand eine Möglichkeit einen (schnellen) I/O-Zugriff auf einem 
normalen Desktop-PC zu realisieren?

Derzeit führe ich auf einem Raspberry Pi diverse Zeitmessungen durch und 
nutzte dazu die GPIO-Pins, die ich mit einem Oszi verbunden habe. Auf 
dem RasPi kann ich direkt mittels C++-Programm auf die entsprechenden 
Register zugreifen, um die Signale zu setzen. Das Ändern einer Flanke 
dauert etwa 10 Nanosekunden.

Nun benötige ich so etwas auf einem Desktop-PC (Intel), der allerdings 
keine GPIOs anbietet. Meine aktuelle Lösung ist die Verwendung des 
nativen RS232-Ports, von dem ich die Signale CTS/RTS nutzen und manuell 
steuern kann. Hier dauert das Ändern der Flanke per LowLevel-Zugriff 
allerdings 3 Mikrosekunden, was für mich schon zu langsam ist (müsste 
<1µs sein).

Alternativen wie GPIOs über USB kommen wohl nicht in Frage, da die 
Latenzzeiten von USB wahrscheinlich zu hoch sind und ich vermutlich auch 
keinen LowLevel-Zugriff bekommen kann (..da USB). ...das einzige was mir 
einfällt wären PCI-Karten, die ich allerdings kaufen müsste und ob diese 
unter Linux funktionieren ist auch ungewiss. ...und Soundkarten wären 
vermutlich zu langsam.

...gibt es am PC irgendwo I/O-Pins, auf die man Low-Level zugreifen 
kann? Hat da jemand Erfahrung?



Gruß,
SBond

von Dr. Sommer (Gast)


Lesenswert?

Martin L. schrieb:
> Alternativen wie GPIOs über USB kommen wohl nicht in Frage,

Kannst du nicht den Befehl oder die Folge an auszugebenden Signalen im 
Voraus per USB an einen Mikrocontroller senden, welcher diese dann mit 
präzisem Timing ausgibt?

Martin L. schrieb:
> Nun benötige ich so etwas auf einem Desktop-PC (Intel)

Warum?

Martin L. schrieb:
> ob diese unter Linux funktionieren ist auch ungewiss

Als erstes brauchst du natürlich ein echtzeit fähiges OS, z.B. RTLinux, 
sonst klappt das schon aus Software Gründen nicht.

von Der Andere (Gast)


Lesenswert?

Martin L. schrieb:
> gibt es am PC irgendwo I/O-Pins

Klar, indem du einen PasPi oder auch einen 8 Bit µC dranhängst und über 
RS232 oder USB steuerst.
Der Kleine macht die präzisen IOs samt Timing der Dicke (PC verarbeitet 
die Daten und gibt die Kommandos.

Schliesslich fährt auch ein 300m Containerriese nicht den Rhein rauf, 
sondern in Rotterdam wird umgeladen.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Martin L. schrieb:
> gibt es am PC irgendwo I/O-Pins, auf die man Low-Level zugreifen kann?

Schon recht lange nicht mehr. Früher konnte man den Frickelport 
verwenden, aber auch der hängt am nachgebildeten ISA-Bus und ist daher 
nicht schneller als direkte I/O-Zugriffe auf das MCR der 8250/16550.

Letzteres ist unappetitlich, weil der Baustein nach wie vor vom normalen 
Devicetreiber angesprochen wird.

Nein, das PC-Hardwaredesign ist nicht dafür ausgelegt, schnelle 
I/O-Aktivitäten mit kurzen Reaktionszeiten zu machen. Daten mit großer 
Bandbreite transportieren, das kann so ein PC, aber banales Pingewackel 
oder auch nur Abfragen davon ist so ohne weiteres nicht drin.


Um eine parallel-I/O-PCI/PCIe-Karte nebst passendem Devicetreiber wirst 
Du kaum herumkommen (und damit meine ich nicht einen Frickelport für den 
PCI/PCIe-Bus).


Alternative: Lagere die zeitkritische low-level-Logik in irgendeinem µC 
aus und schließe den per USB an den PC an.

von Martin L. (sbond)


Lesenswert?

vielen Dank für die Antworten :)

so wie es aussieht bleibt mir also nur der lahme RS232-Zugriff (16550A).

Die Auslagerung ist an sich eine schöne Idee, geht aber in meinem Falle 
nicht, da ich nichts 'externes' messe. Um mal konkret zu werden was ich 
eigentlich damit mache:

Ich möchte unter anderem die Geschwindigkeit von C++-Befehlen messen 
(z.B. Auslesen der Systemzeit, ...und weiteres). C++ bietet natürlich 
Funktionen an um Zeiten zu messen, aber im Nanosekundenbereich sind 
Softwarezeitstempel viel zu ungenau. Daher messe ich derzeit mittels 
I/O-Zugriff und einem Oszi. Egal ob Linux-Kernel oder im Userspace, auf 
dem RasPi kann ich mit einer Genauigkeit von ca. 20ns messen (+/- 
minimalen Jitter durch das OS). Bei Softwaremessungen via std::chrono 
bin ich beim Pi bei ca 1-3µs (deutlich höher).

Bei Desktop-PC bin ich selbst im Linux-Kernel auf 3µs begrenzt, da der 
16550A einfach nicht schneller ist und ich schon direkt im Register 
schreibe. Eine Auslagerung auf externe Hardware (via USB/RS232) ist also 
nicht möglich, da ich mir dann ja noch mehr Latenzen reinhole.

...naja... wäre wohl zu schön gewesen ;)

von Dr. Sommer (Gast)


Lesenswert?

Martin L. schrieb:
> Ich möchte unter anderem die Geschwindigkeit von C++-Befehlen messen
> (z.B. Auslesen der Systemzeit,

Das heißt, du misst die Zeit für System Calls (Uhrzeit abfragen, wobei 
das dank VDSO nicht immer einer ist), über... System Calls (Zugriff auf 
Ports)? Klingt wenig sinnvoll. Mache das im Kernel über die Performance 
Timer von der CPU. ARM hat sowas, x86 bestimmt auch. Auf ARM ist es auch 
möglich (x86 vielleicht auch) einen syscall aus privilegiertem Code 
heraus zu machen, d.h. vorher und nachher den Timer abzufragen. 
Alternativ einfach direkt am Anfang/Ende der Exception messen.
Natürlich sind solche Messungen immer nur Stichproben - die Dauer 
variiert stark dank Cache, Branch Prediction, Scheduling...

von fchk (Gast)


Lesenswert?

Martin L. schrieb:
> Nun benötige ich so etwas auf einem Desktop-PC (Intel), der allerdings
> keine GPIOs anbietet.

Hier solltest Du fündig werden.

https://buy.advantech.eu/Data-Acquisition-Smart-I-O/Data-Acquisition-I-O-Cards-PCIE-I-O-Cards/GPIB.products.htm

Die Leute haben auch Linux-Treiber dafür.

fchk

von dödel (Gast)


Lesenswert?

Unter welchem OS misst du denn? Wenn ein Taskwechsel erfolgt, ist die 
Messung Müll. Unter Linux kann man ggf. die Situation mit einem RT 
Kernel verbessern. Aber unter Win????

von Volker (_volker)


Lesenswert?

Hallo,

schon mal bei Grautier geschaut?

Mini-PCIe - PIC18LF2550 - DevBoard
Beschreibung
Dieses kleines Mini-PCIe Dev-Board, kann man dafür benutzen um kleinere 
Schaltungen im Laptop/Netbook betreiben, alle freien I/O des PIC18LF2550 
sind auf der Topseite vorhanden zusätzlich ist ein kleines Prototypen 
Feld vorhanden.
Der PIC18LF2550 ist per USB und I2C(SMBUS) mit dem Rechner verbunden, 
ich nutze den Bootloder V5 von http://www.Sprut.de um neue Firmware über 
USB Flashen zu können.

https://www.grautier.com/grautier/doku.php/elektronik/devbords/pcie

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Martin L. schrieb:
> ch möchte unter anderem die Geschwindigkeit von C++-Befehlen messen
> (z.B. Auslesen der Systemzeit, ...und weiteres). C++ bietet natürlich
> Funktionen an um Zeiten zu messen, aber im Nanosekundenbereich sind
> Softwarezeitstempel viel zu ungenau.

Der High-Performance-Timer, der in praktisch jedem neuzeitlichen 
Prozessor verbaut ist, lässt "Softwarezeitstempel" mit ziemlich hoher 
Auflösung zu.

Im übrigen solltest Du berücksichtigen, daß so ein Programm auf einem PC 
nie alleine ist - das Betriebssystem funkt beliebig dazwischen, und auch 
die Hardware selbst tut das, indem irgendwelche Interrupts o.ä. aktiv 
werden. Auf den einzelnen Prozessortakt genau wirst Du Deine Zeiten also 
nie bestimmen können.

Mit den High-Performance-Timern aber erhältst Du eine Auflösung, die 
deutlich höher ist als die, die Du mit Pinwackeln an der sehr langsam 
angebundenen seriellen Schnittstelle erreichen kannst.

von Chris (Gast)


Lesenswert?

Wenn man die serielle/parallele io Karte vom legacy Adressraum zum 
memory mapped io umkonfiguriert, dann bekommt man schnelle io Zugriffe.
Bei legacy io müssen waitstates eingefügt werden, im Prinzip sind das 
meistenteils isa Bausteine mit <20mhz Systembus und isa->PCI sowie 
pci->pciE interface IC/asics.

von (prx) A. K. (prx)


Lesenswert?

Martin L. schrieb:
> Ich möchte unter anderem die Geschwindigkeit von C++-Befehlen messen
> (z.B. Auslesen der Systemzeit, ...und weiteres). C++ bietet natürlich
> Funktionen an um Zeiten zu messen, aber im Nanosekundenbereich sind
> Softwarezeitstempel viel zu ungenau.

Genauer gehts nicht, auslesbar per __rdtsc()
https://en.wikipedia.org/wiki/Time_Stamp_Counter

von brummel (Gast)


Lesenswert?

> die Geschwindigkeit von C++-Befehlen messen

Hmm, ist es nicht besser sich den vom Compiler erzeugten Assembler Code 
anzusehen? Ist dann doch klar wie lange die Ausführung braucht.

von (prx) A. K. (prx)


Lesenswert?

brummel schrieb:
> Hmm, ist es nicht besser sich den vom Compiler erzeugten Assembler Code
> anzusehen? Ist dann doch klar wie lange die Ausführung braucht.

Gratulation wenn du mit Befehls-Takte zählen auch nur in die Nähe eines 
passenden Ergebnisses kommst. Heutige x86 CPUs sind ein klein wenig 
komplexer als ein AVR oder Cortex M. Das wurde schon mit dem Pentium Pro 
vor Jahrzehnten schwierig.

: Bearbeitet durch User
von $$$ (Gast)


Lesenswert?

> erzeugten Assembler Code

Vermutlich ist der TO Informatiker, und beherrscht Assembler gar nicht.

von (prx) A. K. (prx)


Lesenswert?

Ich bin auch Informatiker. ;-)

von $$$ (Gast)


Lesenswert?

> Ich bin auch Informatiker. ;-)

Du stellst aber keine dummen Fragen.

von Sebastian S. (amateur)


Lesenswert?

Wenn irgend möglich würde ich mir den direkten Zugriff auf die 
I/O-Anschlüsse verkneifen.
Auf Seite des Betriebssystem wurde sehr viel Aufwand getrieben genau 
dies zu verhindern! Ist ja auch sinnvoll. Egal ob im Fehlerfalle oder 
bei boshafter Absicht.
Soweit mir bekannt geht das nur, indem Du dem System "Deinen" Device 
Driver unterjubelst. Aber auch hier bleibt von der erhofften Echtzeit 
meist nicht viel über.

von (prx) A. K. (prx)


Lesenswert?

Wen so etwas ernsthaft interessiert: Hier steht wie man die Laufzeit von 
Befehlen und Befehls-Sequenzen misst, mit Testprogrammen und Ergebnissen 
für viele x86 CPUs. Und mit einer Beschreibung, wie die intern 
funktionieren.

https://www.agner.org/optimize/

von Matthias K. (kannichauch)


Lesenswert?

Gibt es nicht, nur mit Karte. Die parallel Ports für Drucker, aber heute 
gibt es die nicht mehr. Man kann freie i/o Ports suchen, eine Karte 
dafür kaufen oder bauen, und dann braucht man noch die Kleinigkeit eines 
geeigneten Betriebssystems.

von (prx) A. K. (prx)


Lesenswert?

I/O ist ziemlich weit vom Prozessorkern weg, insbesondere jene, die über 
Restbestände des alten ISA-Busses angebunden sind wie Parport und Async. 
Denn der Prozessorkern arbeitet mit einigen Tausend MHz, die I/O an 
jenen archaischen Teilen von PCs mit einigen MHz. Das Ergebnis sind jene 
3µs, die der TE gemessen hat. Die entsprechen ungefähr 10.000 
CPU-Takten. Ein einziger Zugriffsbefehl auf so eine UART haut 
dementsprechend gewaltig ins Kontor.

: Bearbeitet durch User
von Michael B. (laberkopp)


Lesenswert?

Martin L. schrieb:
> Ich möchte unter anderem die Geschwindigkeit von C++-Befehlen messen
> (z.B. Auslesen der Systemzeit, ...und weiteres). C++ bietet natürlich
> Funktionen an um Zeiten zu messen,

Dafür gibt es doch haufenweise Performance-Zähler im Pentium, damit man 
die unterschiedluchsten Zeiten, Takte, Delays analysieren kann, und zwar 
taktzyklengenau.

Denn das Pipelining und Zwischencode-generieren und Daten-Caching, 
out-of-order execution, Multithreading und Mehrkernverarbeitung macht ja 
jede Zeitmessungung zum Zufallspiel.

https://en.m.wikipedia.org/wiki/Hardware_performance_counter

von brummel (Gast)


Lesenswert?

> Gratulation wenn du mit Befehls-Takte zählen auch nur in die Nähe eines
> passenden Ergebnisses kommst. Heutige x86 CPUs sind ein klein wenig
> komplexer als ein AVR oder Cortex M. Das wurde schon mit dem Pentium Pro
> vor Jahrzehnten schwierig.

Mit diesem Argument kannst du aber dann auch den Hardware Ansatz zur 
Zeitmessung vergessen.

von (prx) A. K. (prx)


Lesenswert?

brummel schrieb:
> Mit diesem Argument kannst du aber dann auch den Hardware Ansatz zur
> Zeitmessung vergessen.

Korrekt, den kann man vergessen, wenn damit Messungen an irgendwelchen 
Pins gemeint sind. Wie ich vorhin bereits schrieb ist das völlig 
sinnlos.

Mit Countern wie dem TSC hingegen geht es. Das hatte ich früher selbst 
so gemacht, ähnlich Agner. Es gibt natürlich ein paar Kleinigkeiten zu 
beachten, im verlinkten Wikipedia-Artikel steht dazu was drin.

: Bearbeitet durch User
von Martin L. (sbond)


Lesenswert?

Erstmal danke für die zahlreichen Antworten

dödel schrieb:
> Unter welchem OS misst du denn? Wenn ein Taskwechsel erfolgt, ist die
> Messung Müll. Unter Linux kann man ggf. die Situation mit einem RT
> Kernel verbessern. Aber unter Win????

Ausschließlich Linux. ;)


Dr. Sommer schrieb:
> Das heißt, du misst die Zeit für System Calls (Uhrzeit abfragen, wobei
> das dank VDSO nicht immer einer ist), über... System Calls (Zugriff auf
> Ports)? Klingt wenig sinnvoll.

der Zugriff auf Ports erfolgt über keine weiteren Calls. Es sei denn ich 
habe dich missverstanden.
1
#include <stdio.h>
2
#include <sys/io.h>
3
4
int main()
5
{
6
    outb(0x2, 0x3f8 + 4); // set RTS
7
    // <do something>
8
    outb(0x0, 0x3f8 + 4); // clear RTS
9
}

asm code:
1
main:
2
  mov edx, 1020
3
  mov eax, 2
4
  outb al,dx
5
  xor eax, eax
6
  outb al,dx
7
  xor eax, eax
8
  ret


Michael B. schrieb:
> Dafür gibt es doch haufenweise Performance-Zähler im Pentium, damit man
> die unterschiedluchsten Zeiten, Takte, Delays analysieren kann, und zwar
> taktzyklengenau.

A. K. schrieb:
> Mit Countern wie dem TSC hingegen geht es. Das hatte ich früher selbst
> so gemacht, ähnlich Agner. Es gibt natürlich ein paar Kleinigkeiten zu
> beachten, im verlinkten Wikipedia-Artikel steht dazu was drin.

Rufus Τ. F. schrieb:
> Der High-Performance-Timer, der in praktisch jedem neuzeitlichen
> Prozessor verbaut ist, lässt "Softwarezeitstempel" mit ziemlich hoher
> Auflösung zu.

ja, das ist richtig. Jedoch ist die Frage wie Genau die Messungen sind 
bzw. wie groß er Jitter ist. ...aber ja... An den Ansatz hatte ich auch 
bereits gedacht.


brummel schrieb:
> Hmm, ist es nicht besser sich den vom Compiler erzeugten Assembler Code
> anzusehen? Ist dann doch klar wie lange die Ausführung braucht.

bedingt, ja. Es gibt zumindest einen Überblick über die Menge der 
ASM-Befehle


=============================================================

wie auch immer..... Vielen Dank für die Tipps und Hinweise.

: Bearbeitet durch User
von (prx) A. K. (prx)


Lesenswert?

Martin L. schrieb:
> ja, das ist richtig. Jedoch ist die Frage wie Genau die Messungen sind
> bzw. wie groß er Jitter ist. ...aber ja... An den Ansatz hatte ich auch
> bereits gedacht.

Im Prinzip ist der TSC taktgenau. Etwas Jitter hast du jedoch immer, 
weil Interrupts reinhauen können, Caches nicht immer den gleichen 
Zustand haben, Speicherzugriffe in Multicore-Umgebungen von der übrigen 
Aktivität abhängen, Hyperthreading mitmischt usw.

> bedingt, ja. Es gibt zumindest einen Überblick über die Menge der
> ASM-Befehle

Was nicht viel bringt, wenn ein Speicherzugriff irgendwas zwischen 0 und 
300 Takten einhandelt.

: Bearbeitet durch User
von Dr. Sommer (Gast)


Lesenswert?

Martin L. schrieb:
> der Zugriff auf Ports erfolgt über keine weiteren Calls. Es sei denn ich
> habe dich missverstanden.

Hm, und du bist sicher dass das "outb" nicht irgendeine Form von Trap, 
Exception, Fault auslöst über die der Kernel dann die Ausgabe erledigt? 
Kenne mich mit x86 nicht so aus. Unter ARM gibt's jedenfalls keine 
outb-Instruktion. Selbst wenn nicht - Zugriffe über den Prozessor-Bus 
auf die entsprechende Peripherie ist unter x86 bestimmt ebenso langsam 
wie unter ARM; die erwähnten Timer sind als Bestandteil der CPU selbst 
deutlich schneller und präziser.

Martin L. schrieb:
> bedingt, ja. Es gibt zumindest einen Überblick über die Menge der
> ASM-Befehle

Hilft aber gar nicht! Die selbe Instruktion kann mal 1 Takt, mal 100 
brauchen - z.B. abhängig davon, ob das Ziel im Cache ist oder nicht...

von Martin L. (sbond)


Lesenswert?

A. K. schrieb:
> Im Prinzip ist das taktgenau. Etwas Jitter hast du jedoch immer, weil
> Interrupts reinhauen können, Caches nicht immer den gleichen Zustand
> haben, Speicherzugriffe in Multicore-Umgebungen von der übrigen
> Aktivität abhängen, Hyperthreading mitmischt usw.

Hast du damit schon öfters gearbeitet?

...nun, ich bin kein Informatiker, weiß aber das hochgenaue 
Zeitmessungen nicht gerade trivial sind. Zeitmessungen auf Hardwarebasis 
ist für mich kein strenges muss, wenn es softwarebasiert auch 
funktioniert. Wichtig ist für mich nur eine Genauigkeit (der 
Zeitmessung) von <= 1µs.

Tatsächlich wollte ich via Hardwaremessung abschätzen, wie lange eine 
softwarebasierte Zeitmessung selbst dauert. Auf dem Raspberry Pi 
funktioniert das auch hervorragend, nur auf einem normalen PC nicht ;)
Zudem gibt es viele Ansätze die Zeitdifferenzen zu messen 
(wall/monotonic clock oder HPC/TSC).

von Martin L. (sbond)


Lesenswert?

Dr. Sommer schrieb:
> Martin L. schrieb:
>> der Zugriff auf Ports erfolgt über keine weiteren Calls. Es sei denn ich
>> habe dich missverstanden.
>
> Hm, und du bist sicher dass das "outb" nicht irgendeine Form von Trap,
> Exception, Fault auslöst über die der Kernel dann die Ausgabe erledigt?
> Kenne mich mit x86 nicht so aus. Unter ARM gibt's jedenfalls keine
> outb-Instruktion. Selbst wenn nicht - Zugriffe über den Prozessor-Bus
> auf die entsprechende Peripherie ist unter x86 bestimmt ebenso langsam
> wie unter ARM; die erwähnten Timer sind als Bestandteil der CPU selbst
> deutlich schneller und präziser.
>


ja richtig, hier ist es Branch with Link
1
main:
2
  push {r4, lr}
3
  mov r1, #1020
4
  mov r0, #2
5
  bl outb
6
  mov r1, #1020
7
  mov r0, #0
8
  bl outb
9
  mov r0, #0
10
  pop {r4, pc}

> Martin L. schrieb:
>> bedingt, ja. Es gibt zumindest einen Überblick über die Menge der
>> ASM-Befehle
>
> Hilft aber gar nicht! Die selbe Instruktion kann mal 1 Takt, mal 100
> brauchen - z.B. abhängig davon, ob das Ziel im Cache ist oder nicht...

...ja, da hast du vermutlich recht

von Dr. Sommer (Gast)


Lesenswert?

Martin L. schrieb:
> ja richtig, hier ist es Branch with Link

Ja nu, das wird eine Funktion in der C-Library aufrufen welche dann 
wahrscheinlich einen Syscall ("svc") macht. Es wäre vorstellbar dass der 
Kernel den Adressraum für die GPIO-Peripherie in den 
User-Space-Adressraum einblendet, aber das wäre doch ziemlich dreckig.

von (prx) A. K. (prx)


Lesenswert?

Martin L. schrieb:
> Hast du damit schon öfters gearbeitet?

Früher, in ähnlichem Interesse wie beim verlinkten Agner Fog (bei ihm 
steckt auch eine Kleinigkeit von mir drin).

> Zudem gibt es viele Ansätze die Zeitdifferenzen zu messen
> (wall/monotonic clock oder HPC/TSC).

Es will ja auch nicht jeder das gleiche wissen. Will man die Taktzyklen 
wissen, was beispielsweise bei Optimierungsaufgaben interessant ist, 
oder will man die Echtzeit wissen. Der Unterschied liegt in der heute 
sehr dynamisch gefahrenen Taktfrequenz.

Beitrag #5882503 wurde vom Autor gelöscht.
von (prx) A. K. (prx)


Lesenswert?

Dr. Sommer schrieb:
> Hm, und du bist sicher dass das "outb" nicht irgendeine Form von Trap,
> Exception, Fault auslöst über die der Kernel dann die Ausgabe erledigt?

Bei x86 gibts im Prozesskontext eine I/O permission bitmap, mit der sich 
einzelne Ports hardwaremässig durchschalten lassen. Andernfalls ist 
ausserhalb des Betriebssystems keine direkte I/O möglich.

: Bearbeitet durch User
von Martin L. (sbond)


Lesenswert?

Dr. Sommer schrieb:
> Es wäre vorstellbar dass der
> Kernel den Adressraum für die GPIO-Peripherie in den
> User-Space-Adressraum einblendet, aber das wäre doch ziemlich dreckig.

seint so zu sein, zumindest kann ich die Befehle nach Beschaffung der 
Rechte im User-Space-Adressraum nutzen.

A. K. schrieb:
> Martin L. schrieb:
>> Hast du damit schon öfters gearbeitet?
>
> Früher, in ähnlichem Interesse wie beim verlinkten Agner Fog (bei ihm
> steckt auch eine Kleinigkeit von mir drin).
>
>> Zudem gibt es viele Ansätze die Zeitdifferenzen zu messen
>> (wall/monotonic clock oder HPC/TSC).
>
> Es will ja auch nicht jeder das gleiche wissen. Will man die Taktzyklen
> wissen, was beispielsweise bei Optimierungsaufgaben interessant ist,
> oder will man die Echtzeit wissen. Der Unterschied liegt in der heute
> sehr dynamisch gefahrenen Taktfrequenz.


ja, da hast du recht ;)

von Dr. Sommer (Gast)


Lesenswert?

Martin L. schrieb:
> zumindest kann ich die Befehle nach Beschaffung der Rechte im
> User-Space-Adressraum nutzen.

Ich glaube eher, dass da einfach ein Syscall gemacht wird. Sonst wäre 
das Programm ja komplett unportabel. ARM hat keine "Ports".

von (prx) A. K. (prx)


Lesenswert?

Dr. Sommer schrieb:
> Ich glaube eher, dass da einfach ein Syscall gemacht wird. Sonst wäre
> das Programm ja komplett unportabel. ARM hat keine "Ports".

Ports gibts durchaus, aber keinen getrennten Adressraum mit eigenen 
Befehlen. Das ist im normalen Adressraum eingeblendet. Beim PC geschieht 
das auch, was neuere Peripherie so circa ab PCI angeht. Mit IN/OUT 
arbeitet nur der alte Kram, und vielleicht irgendwelcher 
Konfigurationskram der Baustein/Slot-Anbindung.

: Bearbeitet durch User
von Sven B. (scummos)


Lesenswert?

Was ist denn das Ziel der ganzen Übung? Normalerweise benutzt man zur 
Messung von Programmlaufzeiten einen Profiler, z.B. perf. Was willst du 
wissen, was perf nicht messen kann?

Sehr detaillierte Informationen, die allerdings nicht unbedingt 
Implementierungsdetails wie den Cache korrekt abbilden, liefert auch 
valgrind --tool=callgrind.

: Bearbeitet durch User
von Martin L. (sbond)


Lesenswert?

Sven B. schrieb:
> Sehr detaillierte Informationen, die allerdings nicht unbedingt
> Implementierungsdetails wie den Cache korrekt abbilden, liefert auch
> valgrind --tool=callgrind.

Callgrind eignet sich in diesem Falle nicht, da es ja eine gewisserweise 
eine Lastverteilung der Funktionen im Code anzeigt. Ansonsten ist 
Valgrind schon eine gute Toolbox ;)


Sven B. schrieb:
> Was ist denn das Ziel der ganzen Übung?

Ganz konkret: Ich möchte periodisch die Ausführungszeit eines 
Programmteils auf unterschiedlichen Hardwareplattformen messen und zwar 
möglichst genau.
Diese Zeit liegt typischerweise im Bereich 10-50 µs. Je nach Last der 
CPU oder OS schwankt die Zeit etwas, was auch mit gemessen werden soll.

Bislang habe ich via std::chrono::high_resolution_clock die Zeit 
gemessen, was prinzipiell auch geht. Allerdings stellt sich mir die 
Frage, wie lange dauert denn der Aufruf dieser Funktionen zur 
Zeitmessung und wie Genau lässt sich damit die Zeit eigentlich messen? 
Daher wählte ich einen hardwarebezogenen Ansatz...

von Dr. Sommer (Gast)


Lesenswert?

Martin L. schrieb:
> wie lange dauert denn der Aufruf dieser Funktionen zur
> Zeitmessung und wie Genau lässt sich damit die Zeit eigentlich messen?

Indem du den fraglichen Programmteil 1000x hintereinander ausführst und 
die gemessene Zeit durch 1000 teilst, erhältst du einen Wert bei dem der 
Funktionsaufruf für die Zeitabfrage insignifikant wird.

von (prx) A. K. (prx)


Lesenswert?

Dr. Sommer schrieb:
> Indem du den fraglichen Programmteil 1000x hintereinander ausführst

Je öfter ein Programmstück dieser Grössenordnung direkt hintereinander 
exakt gleich ausgeführt wird, desto besser wird die Sprungvorhersage 
genau darauf trainiert. Und beim zweiten oder dritten Lauf sind auch die 
Caches in Bestform. Ist jedoch das Programmstück im realen Einsatz von 
viel anderem Kruscht umgeben, ist das Ergebnis deiner Testmethode u.U. 
von schwacher Aussagekraft.

: Bearbeitet durch User
von (prx) A. K. (prx)


Lesenswert?

Martin L. schrieb:
> Diese Zeit liegt typischerweise im Bereich 10-50 µs.

Probiers mal mit __rdtsc(). Nagle den Prozess auf einen Core fest (geht 
z.B. per Task Manager) und nimm Hyperthreading raus (BIOS). Ein paar mal 
probieren musst du es allerdings schon, aber im realistischen 
Gesamtkontext.

: Bearbeitet durch User
von Bernd K. (prof7bit)


Lesenswert?

Schau dir mal sampling profiler wie z.b. oprofile an. Da bekommst du 
erstaunlich detaillierte und aufschlussreiche Ausführungszeiten bis 
hinunter auf einzelne Instruktionen. Und das ganz ohne den Code 
instrumentieren zu müssen!

: Bearbeitet durch User
von Sven B. (scummos)


Lesenswert?

Ich finde auch trotzdem Sampling Profiler bis zu einer Erklärung warum 
das jetzt ausgerechnet in diesem Fall nicht geht die richtige Variante.

Klar sagen die dir nicht, ob jetzt ein sprintf 12 oder 19 Instruktionen 
dauert, aber sie sagen dir eine lange Liste der langsamsten Dinge in 
deinem Programm. Und darum geht's doch im Endeffekt, oder?

von /dev (Gast)


Lesenswert?

Martin L. schrieb:
> ...gibt es am PC irgendwo I/O-Pins, auf die man Low-Level zugreifen
> kann? Hat da jemand Erfahrung?

/dev/mem && /dev/port && /dev/kmem kann man sich per mmap() in den 
Userspace mappen.

von Tom (Gast)


Lesenswert?

Wenn es etwas kosten darf, dann schaue mal nach FPGAs mit PCIe, 
Spartan-6 SP605 Evaluation Board zum Beispiel.

Ja es bedeutet Einarbeitung in FPGA, Verilog bzw. VHDL, aber eine 
schnellere I/O-Kartenlösung fällt mir nicht ein.

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.