Hallo zusammen,
ich muss einen Timer für ein C-Programm programmieren. Der Timer kann
Werte bis zu ca. 100 Milliarden annehmen. Die größte Variable ist
"unsigned long" mit ca. 4 Milliarden. Hat jemand ne Idee, wie ich
mehrere long-Variablen hintereinander schalten kann, um mehr als 4
Milliarden zu speichern?
Manche Compiler unterstützen long long, vielleicht gehört es inzwischen
auch zum Standard, oder du rüstest auf C++ auf und schreibst eine
entsprechende Klasse. Da kannst du dann auch direkt die Operatoren
überladen.
Hanno schrieb:> Du suchst also eine Art Algorythmus, mit dem du auf einfache Weise mehr> als 4 Milliarden in "einem" Speicher ablegen kannst!?
Simpel. Ein solcher Algor*i*thmus sieht so aus:
i = 0
FOREACH byte IN number:
speicher[i] = byte
i += 1
Und schon ist alles im Speicher abgelegt.
Rolf Magnus schrieb:> Dussel schrieb:>> Manche Compiler unterstützen long long, vielleicht gehört es inzwischen>> auch zum Standard,>> Das tut es seit 12 Jahren.
Wie die Zeit vergeht… Tatsächlich habe ich dann davor mit C(++)
angefangen und mich etwa in der Zeit zum letzten Mal mit Datentypen
beschäftigt.
Damit sollte das Problem aber dann gelöst sein
Μαtthias W. schrieb:> Aber das ist in diesem Fall etwas mit Kanonen auf Spatzen geschossen.
Es drängt sich der Verdacht auf, dass auch der Timer bis 100 Mrd. schon
kein so guter Ansatz ist...
Dazu müsste man aber wissen, was überhaupt gezählt werden soll.
Hi
warum? Für sehr exakte Zeitmessungen bietet sich unter Windows
QueryPerformanceCounter an. Und der zählt typischerweise im
Prozessortakt. Damit erreicht man schon nach relativ kurzer Zeit sehr
große Zahlen.
Matthias
Μαtthias W. schrieb:> Und der zählt typischerweise im> Prozessortakt.
nein macht er nicht, sonst müsste man nicht QueryPerformanceFrequency
abfragen, er ist meist 1/1000 vom Takt.
Μαtthias W. schrieb:> Hi>> warum? Für sehr exakte Zeitmessungen bietet sich unter Windows> QueryPerformanceCounter an. Und der zählt typischerweise im> Prozessortakt. Damit erreicht man schon nach relativ kurzer Zeit sehr> große Zahlen.
Schon.
Aber mit den Zahlen muss man ja auch etwas machen.
Und wer schon mal gesehen hat, wie Windows gemächlich ab und an mal den
Speicher aufräumt und Festplattencaches ausleert, der sorgt sich nicht
mehr um ein paar Taktzyklen sondern akzeptiert, dass ein exaktes Timing
unter Windows kleiner als ein paar Millisekunden nicht (oder nur mit
Tricks, aber dann braucht er nicht hier fragen) realisierbar ist. Womit
sich dann auch die großen Zahlen für die Zeiten erübrigen. Denn mit
10Millisekunden und 100 Milliarden sind wir dann bei 30 Jahren
Zählumfang. Und bei derartigen Zählräumen braucht man dann nicht
wirklich einen Zähler der auf 10 Millisekunden genau ist. Da hat das
Windows Update den Rechner in der Zwischenzeit schon ein paar mal
rebootet und das Timing komplett zerstört :-)
Μαtthias W. schrieb:> warum? Für sehr exakte Zeitmessungen bietet sich unter Windows> QueryPerformanceCounter an. Und der zählt typischerweise im> Prozessortakt. Damit erreicht man schon nach relativ kurzer Zeit sehr> große Zahlen.
Ja, und der gibt sogar den Datentyp vor.
Ich schrieb ja: Man müsste wissen, was überhaupt gezählt wird. Und wer
und wie.
Es ist ziemlich witzlos, so einen genauen Zähler loszulassen, wenn man
im präemptiven Multitasking ohnehin nur in unbestimmter Weise Rechenzeit
zugeteilt bekommt, und das bei NT auch nur alle 15 Millisekunden. Oder
wenn man die Aufrufkonvention nicht beurteilen kann und daher nicht
weiß, wie viele Takte dabei noch verloren gehen. Oder weil der
Performance Counter total ungeeignet ist, lange Zeiträume zu messen,
weil man nachher nicht mehr auf die Echtzeit (Sekunden) zurückschließen
kann. Was unter anderem daran liegt, dass die Zählfrequenz von
QueryPerformanceFrequency() nur unzureichend genau bestimmt wird.
Unterm Strich ist der Performance Counter also wertlos für solche
Messungen. Und das wirft halt die Frage auf, was man mit solch
gigantischen Datentypen zählen will.
Peter II schrieb:>> Und der zählt typischerweise im>> Prozessortakt.>> nein macht er nicht, sonst müsste man nicht QueryPerformanceFrequency> abfragen, er ist meist 1/1000 vom Takt.
Du hast das tatsächlich schonmal gemacht? Wirklich? Auf mehr als einem
System? Bisher ist bei meinen Tests immer der nominelle Prozessortakt
rausgefallen.
Sven P. schrieb:> Unterm Strich ist der Performance Counter also wertlos für solche> Messungen. Und das wirft halt die Frage auf, was man mit solch> gigantischen Datentypen zählen will.
Richtig. Evtl. ist Florian aber auch auf einem anderen System unterwegs
wo etwas wie ein OS garnicht mitspielt. Ich wollte damit eigentlich nur
ausdrücken das ein uint32_t manchmal wirklich zu kurz für Zeitmessungen
sein kann. uint64_t sollte aber tatsächlich reichen und gmp stellt dann
eben die Kanonen dar.
Matthias
Sven P. schrieb:
> Evtl. ist Florian aber auch auf einem anderen System unterwegs> wo etwas wie ein OS garnicht mitspielt.
Wer programmiert denn einen PC ohne OS? Aber auch mit OS gibt es ja auch
Echtzeitsysteme. Bei xenomai zählen die Timer in Nanosekunden. Da wären
100 Milliarden nach gut anderthalb Minuten erreicht.
Rolf Magnus schrieb:> Sven P. schrieb:>> Evtl. ist Florian aber auch auf einem anderen System unterwegs>> wo etwas wie ein OS garnicht mitspielt.>> Wer programmiert denn einen PC ohne OS? Aber auch mit OS gibt es ja auch> Echtzeitsysteme. Bei xenomai zählen die Timer in Nanosekunden. Da wären> 100 Milliarden nach gut anderthalb Minuten erreicht.
Wo war denn beim OP die Rede von einem PC? Kann ja sonstwas sein. Und
selbst die POSIX-Funktion clock_gettime liefert einen Zeitstempel zurück
der in Nanosekunden skaliert ist. Allerdings ist die Granulariät liegt
meist die ein oder andere Dekade darüber.
Matthias
Μαtthias W. schrieb:> Peter II schrieb:>>> Und der zählt typischerweise im>>> Prozessortakt.>>>> nein macht er nicht, sonst müsste man nicht QueryPerformanceFrequency>> abfragen, er ist meist 1/1000 vom Takt.>> Du hast das tatsächlich schonmal gemacht? Wirklich? Auf mehr als einem> System? Bisher ist bei meinen Tests immer der nominelle Prozessortakt> rausgefallen.>
MSDN
(http://msdn.microsoft.com/en-us/library/windows/desktop/ms644905%28v=vs.85%29.aspx)
schreibt dazu:
"Retrieves the frequency of the high-resolution performance counter, if
one exists. The frequency cannot change while the system is running."
Vom Prozessortakt ist hier aber nicht Rede, auch wenn deine Tests diesen
ermittelt haben sollten, bei mir kommt z.B. 2862578 heraus und ich habe
einen Intel i7-940 mit 2,93 Ghz.
Der Entwickler schrieb:> Μαtthias W. schrieb:>> Peter II schrieb:>>>> Und der zählt typischerweise im>>>> Prozessortakt.>>>>>> nein macht er nicht, sonst müsste man nicht QueryPerformanceFrequency>>> abfragen, er ist meist 1/1000 vom Takt.>>>> Du hast das tatsächlich schonmal gemacht? Wirklich? Auf mehr als einem>> System? Bisher ist bei meinen Tests immer der nominelle Prozessortakt>> rausgefallen.>>>> MSDN>
(http://msdn.microsoft.com/en-us/library/windows/desktop/ms644905%28v=vs.85%29.aspx)
> schreibt dazu:> "Retrieves the frequency of the high-resolution performance counter, if> one exists. The frequency cannot change while the system is running.">> Vom Prozessortakt ist hier aber nicht Rede, auch wenn deine Tests diesen> ermittelt haben sollten, bei mir kommt z.B. 2862578 heraus und ich habe> einen Intel i7-940 mit 2,93 Ghz.
Ich schrieb ja "typischerweise". Das das nicht garantiert wird ist mir
durchaus bewusst.
Aber nach etwas Recherche scheint das eine Sache des OS + vorhandener
Hardware zu sein. http://www.virtualdub.org/blog/pivot/entry.php?id=106
Es ist also weder so das da typischerweise der Prozessortakt rausfällt
noch so das da 1/1000 eben dieses rausfällt.
Was lernen wir daraus? Wirklich exakte (relative) Zeitmessung ist sehr
stark vom System (OS + Hardware) abhängig auf dem man unterwegs ist.
Matthias
Μαtthias W. schrieb:> Wo war denn beim OP die Rede von einem PC?
Forum: PC-Programmierung
> Kann ja sonstwas sein. Und selbst die POSIX-Funktion clock_gettime> liefert einen Zeitstempel zurück der in Nanosekunden skaliert ist.> Allerdings ist die Granulariät liegt meist die ein oder andere Dekade> darüber.
Klar.
Μαtthias W. schrieb:> Wo war denn beim OP die Rede von einem PC? Kann ja sonstwas sein. Und> selbst die POSIX-Funktion clock_gettime liefert einen Zeitstempel zurück> der in Nanosekunden skaliert ist. Allerdings ist die Granulariät liegt> meist die ein oder andere Dekade darüber.
Mit dem feinen Unterschied, dass die POSIX-Funktionen Zeiten messen,
während der Performance-Zähler nur unspezifisch zählt.
Ich kann mich düster an ein Experiment erinnern, wo der
Performance-Zähler (nach Umrechnung in Echtzeit mit der Frequenz) nach
100 Sekunden Laufzeit schon eine Millisekunde abgedriftet war. Also
genaugenommen, nicht der Zähler, aber die Umrechnung eben.
Selbst für den Fall, dass wir in Hardware denken: Irgendwie muss der
Zählerstand ja ins Programm kommen. Entweder gibt es dann eben einen
ausreichend großen Datentyp (uint64_t meinethalben) oder der Zähler ist
aufgeteilt, zum Beispiel auf zwei Worte zu 32 Bit. Das hat dann
denselben Effekt wie wenn der Zähler regelmäßig überläuft und das
wiederum hat denselben Effekt wie ein simpler Nachteiler.
Sven P. schrieb:> Mit dem feinen Unterschied, dass die POSIX-Funktionen Zeiten messen,> während der Performance-Zähler nur unspezifisch zählt.
Stimmt. Kennt man aber dessen Frequenz kann man damit auch Zeiten
messen.
> Ich kann mich düster an ein Experiment erinnern, wo der> Performance-Zähler (nach Umrechnung in Echtzeit mit der Frequenz) nach> 100 Sekunden Laufzeit schon eine Millisekunde abgedriftet war. Also> genaugenommen, nicht der Zähler, aber die Umrechnung eben.
Und? 100.000:1 sind 10ppm. Das liegt im Bereich der Toleranz des Quarz
der irgendwo den Grundtakt erzeugt. Und was hast du da mit was
verglichen? Performance counter gegen clock_gettime? Zweiteres misst
auch nicht genauer wenn keine zweite Zeitquelle zur Verfügung steht
(z.B. NTP).
Matthias
Μαtthias W. schrieb:> Sven P. schrieb:>> Mit dem feinen Unterschied, dass die POSIX-Funktionen Zeiten messen,>> während der Performance-Zähler nur unspezifisch zählt.>> Stimmt. Kennt man aber dessen Frequenz kann man damit auch Zeiten> messen.
Nein, kann man eben nicht. Zumindest nicht über längere Zeiträume, wobei
'länger' hier die Größenordnung einiger Minuten meint.
Edit sagt noch: Also jein, kann man schon. Aber die Frequenz kennt man
nicht hinreichend genau.
>> Ich kann mich düster an ein Experiment erinnern, wo der>> Performance-Zähler (nach Umrechnung in Echtzeit mit der Frequenz) nach>> 100 Sekunden Laufzeit schon eine Millisekunde abgedriftet war. Also>> genaugenommen, nicht der Zähler, aber die Umrechnung eben.>> Und? 100.000:1 sind 10ppm. Das liegt im Bereich der Toleranz des Quarz> der irgendwo den Grundtakt erzeugt. Und was hast du da mit was> verglichen?
Den Performance-Zähler mit der Systemzeit (Systemzeit, nicht
RTC-Baustein). Theoretisch laufen beide absolut synchron, die
Quarztoleranz spielt ja dabei keine Rolle, denn sie würde beide Zeiten
betreffen.
Sie laufen auch sicherlich synchron, aber die Umrechnung über
QueryPerformanceFrequency() ist nur unzureichend genau.
Edit sagt: Zum Nachlesen:
http://msdn.microsoft.com/en-us/magazine/cc163996.aspx
Das trifft mein Experiment recht genau.
Μαtthias W. schrieb:> Sven P. schrieb:>> Mit dem feinen Unterschied, dass die POSIX-Funktionen Zeiten messen,>> während der Performance-Zähler nur unspezifisch zählt.>> Stimmt. Kennt man aber dessen Frequenz kann man damit auch Zeiten> messen.
Nur daß die halt in Zeiten von dynamischer Unter- und mittlerweile auch
Übertaktung nicht mehr konstant ist. Dazu kommen dann noch spontane
Offsets durch Task-Migration zwischen mehreren Cores oder CPUs.
Rolf Magnus schrieb:> Nur daß die halt in Zeiten von dynamischer Unter- und mittlerweile auch> Übertaktung nicht mehr konstant ist.
das sollte sie aber sein, sonst macht das ganze überhaupt keinen sinn.
Denn die cpu ist bei einem normale PC ständig am schlafen und damit in
der Untertaktung.
> Dazu kommen dann noch spontane> Offsets durch Task-Migration zwischen mehreren Cores oder CPUs.
jeder Core hat ihren seinen eigenen Zähler mann muss nur darauf achten
das man immer den gleichen zu verwenden.
Rolf Magnus schrieb:> Nur daß die halt in Zeiten von dynamischer Unter- und mittlerweile auch> Übertaktung nicht mehr konstant ist. Dazu kommen dann noch spontane> Offsets durch Task-Migration zwischen mehreren Cores oder CPUs.
Diese Probleme beziehen sich auf den Time Stamp Counter der CPU und die
Instruktion RDTSC, die diesen ausliest. Siehe
http://en.wikipedia.org/wiki/Time_Stamp_Counter
QeryPerformanceCounter nutzt diesen wenn nötig, aber falls der Rechner
einen eigenen Multimedia-Timer hat, wird dieser stattdessen genutzt und
damit diese Problematik umgangen. Siehe
http://msdn.microsoft.com/en-us/library/ee417693(VS.85).aspx
Irgendwo ist nen Grundtakt von dem sich alle Takte ableiten ABER
dazwischen sind etliche PLLs, die durch Frequenz bzw Phasenrückkopplung
in einem bestimmeten intervall schanken. Zusätzlich gibt es noch so
schöne Sachen wie Spread Spektrum und dynamisches Takten von etlichen
Komponenten. Bei Spread Spektrum wird der Takt absichtlich gespreizt
(gespeept bzw. gewobbelt) um die im HF abgestrahlte Leistung nicht so
schmalbandig auf einer Frequnz abzustrahlen. Da ist nichts mehr mit
genau.
Da gibt es nur noch die Echtzeituhr mit ihrem Uhrenquarz. Und wenn der
zu wenig Auflösung (Zeitauflösung bzw. Frequenz) bietet dann mußt du
halt Zusatzhardware einbauen.