Funktion über Zeitspanne gleichverteilt aufrufen
-
#include <clock.h> int n=0,calls_per_second=20000; clock_t t; for(;;) { t=clock(); n+=calls_per_second; while(n>=CLOCKS_PER_SEC) { funktion(); n-=CLOCKS_PER_SEC; } while(clock()<=t); }braucht leider ein bißchen viel cpu-zeit. eine lösung mit Sleep() wäre ebenfalls möglich, aber ich muß jetzt in die heia :p
-
Danke Konfusius.
Da ich aber so wenig CPU wie möglich verbrauchen will/muss hab ich folgendes ausprobiertHANDLE hTimer = NULL; LARGE_INTEGER liDueTime; QueryPerformanceFrequency( (LARGE_INTEGER*) &Frequency); hTimer = CreateWaitableTimer(NULL, TRUE, "WaitableTimer"); int i=0; while(i<30000) { //Berechne Zeit für einen Funktionsaufruf QueryPerformanceCounter(&TU_Start); MyFunction(); QueryPerformanceCounter(&TU_End); //Berechne Zeit die bis zum 1/500-tel Sekunde zu warten ist liDueTime.QuadPart =(long) -(((double)1/500 - (double)(TU_End.QuadPart-TU_Start.QuadPart)/(double)Frequency.QuadPart)*10000000); //Setze Timer if (!SetWaitableTimer(hTimer, &liDueTime, 0, NULL, NULL, 0)) { printf("SetWaitableTimer failed (%d)\n", GetLastError()); return 2; } //Warte auf Timer if (WaitForSingleObject(hTimer, INFINITE) != WAIT_OBJECT_0) printf("WaitForSingleObject failed (%d)\n", GetLastError()); i++; }Der Code funktioniert auch wunderbar, aber leider nur bis 100 Funktionsaufrufe/sec. Es ist egal ob ich 1/500 1/20000 schreib, der macht immer nur 1/100. woran könnte es liegen??
-
Dein Code:
QueryPerformanceCounter(&TU_Start); MyFunction(); QueryPerformanceCounter(&TU_End);Hat das Problem, dass wahrscheinlich immer eine Zeitdifferenz nahe 0 rauskommt.
Die Granularitaet des Performance Counters kannst Du mittels QueryPerformanceFrequency() abfragen. Sie liegt z.B. bei ca. 600 kHz.
Wenn Deine Funktion schneller ist, bekommst Du als Zeitdifferenz 0.
Du musst also von der Granularitaet ausgehend, die Du mit QueryPerformanceFrequency() abgefragt hast, die Berechnung fuer die Zeitdauer eines Intervalls berechnen.
Da bei Windows die tatsaechliche Granularitaet des Timings zwischen z.B. 600 kHz und 50 Hz liegt, also Dein Thread unter Umstaenden gar nicht rechtzeitig drankommt, wenn der Timer abgelaufen ist, kann der tatsaechliche Rhythmus Deiner Funktionsaufrufe stark schwanken.
Aber probier's ruhig mal aus.
-
TU_End-TU_Start = 14
FrequencyCounter = 3579545
=>3,9111....*10hoch-6 also nicht 0
Ich hab den Process schon mal mit realtime laufen lassen, kommt der gleiche Wert raus. Nie mehr als 100mal pro sekunde. Wenn ich das ganze ohne Timer durchlaufen lass, z.B. in einer Endlosschleife, erreiche ich Werte von bis zu 100000mal/sec, allerdings bei 100% CPU-Last. Ich möchte nun die Last reduzieren indem ich z.B. nur 20000mal/sec die Funktion aufrufe.
-
Vampy20 schrieb:
Ich hab den Process schon mal mit realtime laufen lassen, kommt der gleiche Wert raus. Nie mehr als 100mal pro sekunde. Wenn ich das ganze ohne Timer durchlaufen lass, z.B. in einer Endlosschleife, erreiche ich Werte von bis zu 100000mal/sec, allerdings bei 100% CPU-Last. Ich möchte nun die Last reduzieren indem ich z.B. nur 20000mal/sec die Funktion aufrufe.
Damit hast Du aber das Problem, dass Du nicht vorhersehen kannst, wie schnell Deine Funktion ueberhaupt ausgefuehrt wird, und ob dann z.B. 20000 mal ueberhaupt noch moeglich sind.
Besser ist in dem Fall, Du gibst einfach den Rest Deiner Zeitscheibe ab:
Sleep(0); // Auf Ende der Zeitscheibe wartenDamit sollte die CPU-Last etwas sinken.
Du kannst natuerlich durch verschiedene Messungen feststellen, wie lange Deine Funktion im Durchschnitt braucht, und anhand dessen ausrechnen, wieviel Prozent der Rechenzeit Du beanspruchen willst und dann entsprechend lange warten.
ULONGLONG GetCPUTicks( void ) { _asm { rdtsc } } ULONGLONG GetFuncTicks( void ) { ULONGLONG t0, t1, diff; t0 = GetCPUTicks(); func(); // Deine Funktion t1 = GetCPUTicks(); diff = ti1 - ti0; return diff; } ULONGLONG GetFuncAverageTicks( void ) { // den Test z.B. 100 mal ausfuehren, um einen Mittelwert zu bekommen ULONGLONG sum = 0; for ( int i=0; i < 100; ++i ) { sum += GetFuncTicks(); } return sum / 100U; }Von da aus auf einen Sleep()-Wert zu kommen, musste selber ausrechnen!

-
bin wieder wach

hier nun eine getestete version, die kaum mehr cpu-zeit verbraucht:
#include <windows.h> #include <iostream> using namespace std; void funktion () { cout<<"."; } int main () { unsigned _int64 calls_per_hour=3600, n=0,t,t_prev,dt; SYSTEMTIME systime; GetSystemTime(&systime); SystemTimeToFileTime(&systime,reinterpret_cast<FILETIME*>(&t)); for(;;) { t_prev = t; GetSystemTime(&systime); SystemTimeToFileTime(&systime,reinterpret_cast<FILETIME*>(&t)); dt = (t-t_prev)/10000L; // time in milli-seconds n+=dt*calls_per_hour; while(n>=3600000L) { funktion(); n-=3600000L; } Sleep(3600000L/calls_per_hour); } return 0; }
-
hi, bin im programmiern noch blutiger anfänger un hab da jetzt n ähnliches problem, nur nicht ganz so kompliziert denk ich^^
hier mein programm: einfaches würfelspiel was fragt ob gewürfelt werden soll, nach eingabe "j" wird gewürfelt mit 2 würfeln (random ausgabe). nebenbei soll ne zeitschleife laufen die alle 5minuten nachdem man wieder "j" zum würfeln eingegeben hat nen 3er pasch ausgibt.
dachte da an sowas wie if(time-gepseichertertimestamp>300) mach paschausgabe else random nur mangelts mir an der umsetzung^^do
{
cout << "Wuerfeln? (j/n)";
cin >> würfeln;
if (würfeln == 'j')srand( time(NULL) );
int w1 = rand() % 6 + 1;
int w2 = rand() % 6 + 1;
printf("Wuerfel 1: %d\nWuerfel 2: %d\n%s", w1, w2, (w1==w2) ? "Pasch!\n" : ""); } while (würfeln == 'j');so sieht das zur zeit aus, hoffe mir kann da jemand weiterhelfen

-
Warum verwendest du printf lieber std::cout
srand( time(NULL) ); do { cout << "Wuerfeln? (j/n)"; cin >> würfeln; if (würfeln == 'j') { int w1 = rand() % 6 + 1; int w2 = rand() % 6 + 1; cout << "w1=" << w1 << " und w2=" << w2 << endl; if (w1 == w2) cout << "Pasch!" << endl; } }while (würfeln == 'j');
-
danke dafür schonmal^^ hatte mir den würfelcode aus nem forum geholt, deswegen hab ichs einfach so stehn lassen

-
wie kann ich denn die zeit überhaupt speichern. ich brauch ja erstmal die startzeit nachdem das erste mal gewürfelt wurde.
-
#include <iostream> #include <time.h> // contains clock() using namespace std; int main() { double time1=0.0, tstart; // time measurment variables // read data tstart = clock(); // start // some code time1 += clock() - tstart; // end time1 = time1/CLOCKS_PER_SEC; // rescale to seconds or "/ 1000" cout << " time = " << time1 << " sec." << endl; return 0; }
-
hmm danke aber damit funktionierts irgendwie nich so wirklich

-
willst du boost verwenden?
#include <boost/thread.hpp> class delayer { boost::system_time last_delay; boost::time_duration delay_time; public: delayer(boost::time_duration delay) : last_delay(boost::get_system_time()), delay_time(delay) {} void delay() { last_delay = std::max(last_delay + delay_time, boost::get_system_time()); boost::this_thread::sleep(last_delay); } }; delayer d(boost::posix_time::microseconds(50)); for (;;) { foo(); d.delay(); // Wartet bis die 50 Millisekunden verstrichen sind }
-
Ups, ich habe auf die ursprüngliche Frage geantwortet.
-
Aber boost::thread::get_system_time() sollte schon einmal einen Tipp geben, wie man Zeit speichert.
-
zween schrieb:
hmm danke aber damit funktionierts irgendwie nich so wirklich

Du musst schon Code zeigen was du machst, sonst kann dir nicht geholfen werden.
-
do{ cout << "Wuerfeln? (j/n)"; cin >> würfel; if (würfel == 'j'){ srand( time(NULL) ); gettime //zeitspeichern ka wie, if(time>5min) ausgabe w1=3 und w2=3, danach zeit resetten und neustart nach erneutem würfeln. int w1 = rand() % 6 + 1; int w2 = rand() % 6 + 1; cout << "Wuerfel 1=" << w1 << endl <<"Wuerfel 2=" << w2 << endl; if (w1 == w2) cout << "Pasch!" << endl; } }while(würfel == 'j');ums nochmal zu erklärn: nach dem ersten mal würfeln soll der timer gestartet werden der nach ablauf der 5min beim erneuten würfeln ein 3er pasch anstatt der random variante ausgibt. danach soll der timer resettet un neu gestartet werden.
-
#include <iostream> #include <cstdio> #include <ctime> // contains clock() using namespace std; int main() { double tstart; // time measurment variables char würfeln; tstart = clock(); srand( time(NULL) ); do { cout << "Wuerfeln? (j/n)"; cin >> würfeln; if (würfeln == 'j') { if (clock() - tstart < 5000) { int w1 = rand() % 6 + 1; int w2 = rand() % 6 + 1; cout << "w1=" << w1 << " und w2=" << w2 << endl; if (w1 == w2) cout << "Pasch!" << endl; } else { cout << "w1=3 und w2=3" << endl; cout << "Pasch dank schummeln!" << endl; tstart = clock(); } } }while (würfeln == 'j'); return 0; }Ist doch nicht so schwer das eine und das andere zusammenzubasteln?
-
aaaah super dank dir! ich hatte einfach n fehler drin. wie gesagt bin noch blutiger anfänger
