Toon posts:

[VC6.0] timen van een funtie

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik zou willen timen hoe lang een functie nu precies geduurd heeft.
Momenteel doe ik een GetTickCount voor en één na de functie. Dit resulteert in een tijd in ms. Echter als ik nu zelfde routine een paar keer na elkaar uitvoer, bekom ik niet telkens dezelfde tijd.

Dan dacht ik, windows probleem met multithreading, even interrupts uitschakelen voor routine en weer inschakelen erna met _asm cli en _asm sti.

Probleem is nu echter dat de routine nu 0ms duurt :( er wordt dus niks uitgevoerd.
Wat doe ik verkeerd?

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Ja, en? Ik mag hopen dat de tweede keer dat je ene functie aanroept dat ie dan sneller is, met cache en zo. Als je time slice echter op is, dan wordt jouw code echt wel uit de cache gemikt. Nog zoiets: Branch prediction, dat kan ook dynamisch de runtime beinvloeden. Er is dus niet zoiets als "de" tijd die een functie duurt.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Verwijderd

Topicstarter
MSalters schreef op 14 april 2004 @ 23:59:
... Er is dus niet zoiets als "de" tijd die een functie duurt.
Als mijn functie nu altijd evenveel instructies uitvoert. Er is toch zoiets als aantal cycli*tijd 1 klokcyclus.
Net als vb in een µC kan 'de' tijd van een routine bepaald worden met aantal cycli*(XTALfreq/4).
Kan dit dan niet met een windows gericht systeem?

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 23:14
De 10ms resolutie van GetTickCount() is natuurlijk veel te weinig. Je kunt beter een groter stuk code testen (groot aantal functieaanroepen in een lusje bijvoorbeeld, al heb je dan wel wat cache voordeel ten opzichte van normaal gebruik), of als je per se een enkele aanroep wil timen gebruik maken van QueryPerformanceCounter. Zie bijvoorbeeld KB 172338.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:03

.oisyn

Moderator Devschuur®

Demotivational Speaker

Of je gebruikt GetThreadTimes (), waarmee je alleen de tijd meet dat de thread aan de beurt is geweest. Maar zoals MSalters al zei hoeft er door cache, pipelining en branchprediction nooit hetzelfde antwoord uit te komen (goed, je hebt natuurlijk theoretisch niet een oneindige verzameling van uitkomsten, maar het kan dus wel per aanroep verschillen)

Overigens kun je interrupts niet aan en uitschakelen in usermode, zou wat zijn als dat wel kon ;)

[ Voor 16% gewijzigd door .oisyn op 15-04-2004 01:19 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Topicstarter
Ik gebruik nu de veel nauwkeuriger time stamp counter

C++:
1
2
3
4
5
6
7
8
9
10
11
unsigned int l1,h1; 

_asm 
{ 
pushad 
cpuid 
rdtsc 
mov l1, eax  
mov h1, edx 
popad  
}

De teruggekregen waarden lopen voor mij nog teveel uiteen waarschijnlijk omdat windows mijn cpu time afsnoept.
Kan ik geen prioriteit instellen voor mijn funtie, zodat windows zo weinig mogelijk cpu tijd gebruikt.
edit:
tikfoutje in programmacode

[ Voor 7% gewijzigd door Verwijderd op 15-04-2004 14:42 ]


Verwijderd

Topicstarter
De prioriteit probeer ik nu te setten met SetThreadPriority()
Echter is dit nog niet de hoogste prioriteit, als ik in MyThread nu een Sleep(1000) steek (=delay 1sec), dan zou ik toch gedurende die seconde niet met de muis kunnen bewegen. Dit lukt dus wel, dus worden er toch nog windows messages afgehandelt.
Ik wil deze dus uit MyThread houden, maar hoe?
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//...

HANDLE g_Thread;

DWORD WINAPI MyThread(LPVOID lpParameter) 
{
    unsigned int l1,h1,l2,h2; 
    _asm 
    { 
    pushad 
    cpuid 
    rdtsc 
    mov l1, eax  
    mov h1, edx 
    popad  
    }

    cout<<"Dit is mijn thread met hoogste prioriteit"<<endl;
    Sleep(1000);
    //... Hier moet de uiteindelijke functie komen

    _asm 
    { 
    pushad
    cpuid 
    rdtsc 
    mov l2 ,eax 
    mov h2, edx
    popad 
    }
    cout<<((l2-l1)*(1.0/450000000))*1000<<"ms"<<endl;
    return 0;
}

main() 
{               
    DWORD l_Dummy;
    g_Thread = CreateThread(NULL, 0, MyThread, NULL, 0, &l_Dummy); 
    
    if(SetThreadPriority(g_Thread,THREAD_PRIORITY_TIME_CRITICAL))
        cout<<"prioriteit setten gelukt"<<endl;
    else
        cout<<"kan prioriteit niet setten"<<endl;


}


offtopic:
even een offtopic vraagje: Nog mensen die problemen krijgen met de compiler bij het gebruik van inline assembler? Compiler: Microsoft Visual Studio 6.0.
Zo ja, hoe te verhelpen?

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:03

.oisyn

Moderator Devschuur®

Demotivational Speaker

Windows is geen real-time OS, dus verwacht ook geen real-time eigenschappen

Met Sleep () gaat je thread ook in slaapstand, zodat een andere thread aan de beurt kan, logisch dus. Bovendien genereert je muis interrupt requests, die sowieso afgehandeld gaan worden, hoe hoog je prioriteit ook is.

Zoals ik al zei, gebruik GetThreadTimes ()

En wat zijn "problemen met inline assembler"? Registers pushen en poppen is niet nodig, VC++ kent de instructies en weet dus welke registers er door jouw code gewijzigd worden, en bewaart de belangrijke registers dus zelf door push/pop instructies om je asm heen te zetten

[ Voor 29% gewijzigd door .oisyn op 15-04-2004 16:11 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Juicy
  • Registratie: December 2000
  • Laatst online: 15:38
Waarom gebruik je geen profiler ?!

-


Verwijderd

Topicstarter
Zal ik eens proberen, maar wat is het verschil tss usermode en kernelmode?

BOOL GetThreadTimes(
HANDLE hThread, // specifies the thread of interest
LPFILETIME lpCreationTime, // when the thread was created
LPFILETIME lpExitTime, // when the thread was destroyed
LPFILETIME lpKernelTime, // time the thread has spent in kernel
// mode
LPFILETIME lpUserTime // time the thread has spent in user mode
);


Eigenlijk nog niet helemaal wat ik zoek. Maar aan de reacties te horen is het dus niet mogelijk om enkel mijn thread uit te voeren.

Verwijderd

Topicstarter
Juicy schreef op 15 april 2004 @ 16:11:
Waarom gebruik je geen profiler ?!
Euhm,.. omdat ik dat niet ken. Wat is een profiler juist?
(Ben dus geen full-time devver, maar hobbyist :) )

Verwijderd

Topicstarter
.oisyn schreef op 15 april 2004 @ 16:10:
En wat zijn "problemen met inline assembler"? Registers pushen en poppen is niet nodig, VC++ kent de instructies en weet dus welke registers er door jouw code gewijzigd worden, en bewaart de belangrijke registers dus zelf door push/pop instructies om je asm heen te zetten
offtopic:
Na het uivoeren van mijn programma, loopt de compiler plots vast als ik aan het tikken ben. Ik kan niets meer doen. ctrl-alt-del en afsluiten die handel.
Programma nochtans op een correcte manier afgesloten.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:03

.oisyn

Moderator Devschuur®

Demotivational Speaker

[Met de Afbeeldingslocatie: http://gathering.tweakers.net/global/templates/got/images/icons/edit.gif knop kun je je berichten wijzigen, en dus ook wat toevoegen]

Punt 1:
Je wilt weten hoe lang je routine draait. Aangezien het niet mogelijk is om in usermode (dat is de security-level waarin applicaties op je OS draaien) te zorgen dat alleen jouw thread aan de beurt is, moet je de tijd weten hoe lang je thread in usermode gespendeerd heeft. Dat kan met GetThreadTimes ().

Punt2:
Een profiler is een tool waarmee je kunt zien hoeveel tijd stukken code in je programma innemen en hoe vaak ze zijn aangeroepen. Het geeft dus een goed beelt van waar de bottleneck zit en waar je moet optimaliseren.

Punt3:
Heb je service pack 6 voor visual studio 6 al?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Verwijderd schreef op 15 april 2004 @ 16:06:
De prioriteit probeer ik nu te setten met SetThreadPriority()
Echter is dit nog niet de hoogste prioriteit, als ik in MyThread nu een Sleep(1000) steek (=delay 1sec), dan zou ik toch gedurende die seconde niet met de muis kunnen bewegen. Dit lukt dus wel, dus worden er toch nog windows messages afgehandelt.
Ga gewoon eens wat in MSDN lezen voordat je het vraagt :/

Thread priorities zijn relatief aan het proces. Het proces heeft zelf ook een priority class die de hoofdgroep aangeeft (hint: SetPriorityClass). Uit de combinatie van die 2 factoren (en eventuele tijdelijke boosts) volgt een getal tussen 0 en 31, wat de absolute prioriteit is van een thread. Dat getal kun je alleen sturen, niet zetten: theoretisch ontvangt een thread op 31 alle CPU tijd zolang hij niet yield, maar in de praktijk zal een preemptive multitasking OS als WinNT altijd nog wel wat slices bedelen aan andere threads, dat is tenslotte het idee erachter dat rogue processen niet alle andere threads in het systeem kunnen starven. Uit ervaring kan ik je wel melden dat op de hoogst mogelijke prioriteit je muis vrijwel onhanteerbaar is :)

Je opmerking hier is sowieso onzin, want tijdens een Sleep(1000) zit je thread te sleepen, oftewel krijgen andere threads alle ruimte die ze willen. Zolang je thread de CPU niet bezig houdt boeit z'n prioriteit niet.

[ Voor 9% gewijzigd door curry684 op 15-04-2004 17:33 ]

Professionele website nodig?


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Ik geloof sowieso niks van de bewering. Als Windows een timeslice pakt, dan is dat meteen een serieuze. Je krijgt dus voor snelle functies (minder dan een timeslice) een distributie waarbij de snelle fractie niet interrupted was, de volgende piek een keer, en een heel klein piekje twee keer.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 23:14
Wat was er nou precies mis met het gebruik van QueryPerformanceCounter()? Ik vind het best als m'n suggestie niet voldoet, maar ik heb nu het idee dat 'ie gewoon genegeerd wordt.

Verwijderd

Topicstarter
Soultaker schreef op 15 april 2004 @ 19:31:
Wat was er nou precies mis met het gebruik van QueryPerformanceCounter()? Ik vind het best als m'n suggestie niet voldoet, maar ik heb nu het idee dat 'ie gewoon genegeerd wordt.
Heb ik ook geprobeerd, maar voldoet niet voor mijn toepassing.
Ik zou eigenlijk een functie willen uitvoeren die niet onderbroken wordt door andere messages. Dit blijkt met windows niet te lukken.

Zou dit met een ander besturingssysteem dan wel lukken? Vb. Linux. Is dit een real-time OS?

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 21-05 14:59

pjvandesande

GC.Collect(head);

Verwijderd schreef op 15 april 2004 @ 16:23:
[...]

Euhm,.. omdat ik dat niet ken. Wat is een profiler juist?
(Ben dus geen full-time devver, maar hobbyist :) )
Een profiler is een programma die met jou programma meekijkt en precies vertel welke functie welke tijd in beslag heeft genomen. Gaat vaak toch enkele statements precies en meer.

Zoek maar is op google naar een profiler voor VB6.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:03

.oisyn

Moderator Devschuur®

Demotivational Speaker

Verwijderd schreef op 15 april 2004 @ 19:45:
Zou dit met een ander besturingssysteem dan wel lukken? Vb. Linux. Is dit een real-time OS?
Nee, en google is je vriend
questa schreef op 15 april 2004 @ 19:48:
Een profiler is een programma die met jou programma meekijkt en precies vertel welke functie welke tijd in beslag heeft genomen. Gaat vaak toch enkele statements precies en meer.

Zoek maar is op google naar een profiler voor VB6.
Ten eerste is dit VC6, en ten tweede: roep je altijd dingen die al gezegd zijn :? Dat valt me de laatste tijd erg van je op namelijk

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Soultaker schreef op 15 april 2004 @ 19:31:
Wat was er nou precies mis met het gebruik van QueryPerformanceCounter()? Ik vind het best als m'n suggestie niet voldoet, maar ik heb nu het idee dat 'ie gewoon genegeerd wordt.
Dat het absolute tijden geeft, en dus absolute tijdsduren, beinvloed door de scheduler. De TS verwacht een constate tijdsduur, ondanks de effecten van schedulers, pipelines, branch prediction, cache, memory latency, swap, temperatuurseffecten, ECC, etcetera.
Kortom: je kunt niet meten wat niet bestaat.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Soultaker schreef op 15 april 2004 @ 19:31:
Wat was er nou precies mis met het gebruik van QueryPerformanceCounter()? Ik vind het best als m'n suggestie niet voldoet, maar ik heb nu het idee dat 'ie gewoon genegeerd wordt.
Totaal niets, QueryPerformanceCounter werkt perfect :) Voor structurele profiling is GetThreadTimes overigens beter, omdat het dus onafhankelijk werkt van de load van het systeem.

Zie ook uit de prehistorie: [rml][ C/C++/Asm] Benchmarking[/rml] :+

Professionele website nodig?

Pagina: 1