depends on the thread, but many times execution time is not measurable because it happens too quickly.
But generally you would call time functions when the thread starts and again when it ends, then execution time is the difference between those two times. Call clock() to get time in milliseconds (for most operating systems). On MS-Windows you can use QueryPerformanceCounter()
Ancient Dragon
Retired & Loving It
30,049 posts since Aug 2005
Reputation Points: 5,662
Solved Threads: 2,343
You are in a multi-threaded environment. Other threads in your application are taking time slices. Other applications are pre-empting and taking time slices. What I usually do is bump my application priority up to real time, set that's thread priority to real time., and then call the function N=10,000 times or so and divide by N to get an approximate time.
The RDTSC assembly instruction can be called before and after and the difference taken!
static uint tclkl, tclkh;
void CpuDelaySet(void)
{
__asm {
rdtsc ; Read time-stamp counter
mov tclkl,eax ; Save low 32bits
mov tclkh,edx ; Save high 32bits
};
}
uint CpuDelayCalc(void)
{
uint v;
__asm {
rdtsc ; Read time-stamp counter
sub eax,tclkl
sbb edx,tclkh ; edx:eax = total elapsed interval
mov v,eax
};
return v;
}
wildgoose
Practically a Posting Shark
896 posts since Jun 2009
Reputation Points: 546
Solved Threads: 99
In its simplest form....
uint nRepeat = 10000;
uint nTotTime;
double fTime;
CpuDelaySet();
for (uint n = 0; n < nRepeat; n++)
{
vD = MyFunc( vA, vB );
}
nTotTime = CpuDelayCalc();
nOnce = nTotTime / nRepeat;
or
nOnce = (nTotTime + (nRepeat>>1)) / nRepeat;
or
fTime = ((double)nTotTime) / ((double)nRepeat);
Note that I'm only returning a 32-bit value so the idea is to not overflow it! 0xffffffff ( 4,294,967,295)
The idea is to repeat the same test N times. In this example I chose 10,000 times. But I recommend to start around 1000 and work up until total time doesn't exceed a 32-bit unsigned value!
This is essentially an average result. You are still being pre-empted, then numbers will be all over the place each run. But they'll be mostly in the ball park. I use this technique to see if optimizations to my function make the function's time increase or decrease!
The RDTSC instruction is a 64-bit value, which contains the number of clock cycles that have elapsed and is accessible from the Application Ring meaning non-system software have access to it! Win32 hasn't blocked access so it is available for reading. It is set to zero at processor reset and merely rolls over to zero when the high count is reached!
wildgoose
Practically a Posting Shark
896 posts since Jun 2009
Reputation Points: 546
Solved Threads: 99
AFAIK it is not possible to time a specific thread as if that thread were the only thing running on the operating system (windows in this case). One reason for that is because the os will perform thousands of context switches while the thread is running, so any time you try to calculate will include the time all those other things are doing as well. So any profiling you attempt will only be approximates, not absolutes.
Ancient Dragon
Retired & Loving It
30,049 posts since Aug 2005
Reputation Points: 5,662
Solved Threads: 2,343
Anything you try will be ballpark. One work around is to run test like I said, then encode into your program the approximate average that gets added to a bucket for each worker thread doing the same task. It won't be accurate, but will be in the ballpark. I think its the best you're going to do.
But keep in mind that it won't be accurate. Don't forget to get the samplings in a release build with your optimization turned on but make sure it is outside the scope or the optimizer will re-arrange your code and the tracking tags won't be where you think they are!
wildgoose
Practically a Posting Shark
896 posts since Jun 2009
Reputation Points: 546
Solved Threads: 99
If you're trying to monitor worker thread usage, then keeping a task count per thread would be just as effective!
You mentioned several threads doing the same job thus that indicates worker threads. I'm assuming you have a number crunching task so find the number of CPU's you have then multiply by two. That is the number of worker threads you'll need for that one task to be most efficient and to run your processor dry. You can request which processor a thread is spawned from but the processor decides. Though you can override it. Over request your threads the read which CPU it is running on. Once you have the distribution you want, then release the ones you don't want! Kind of crude but its the only way I know to override the Operating System logic. Because as I mentioned, you're only requesting a CPU, that doesn't mean it has to give it to you!
wildgoose
Practically a Posting Shark
896 posts since Jun 2009
Reputation Points: 546
Solved Threads: 99
When you spawn the thread you pass a void user value!
Why not pass a boolean pointer! Loop while it is set and when false fall out of the thread loop. Don't forget your thread exit function for proper cleanup.
void MyWorker( void *foo )
{
bool *pbSignal = (bool *)foo;
while (foo)
{
}
}
Or pass in a local index for that worker thread.
void MyWorker( void *foo )
{
uint idx = (uint)foo;
while ( gbAppActive == true )
{
}
gThreadActive[ idx ] = false; // Tell root that this thread is shut down
}
In application root cleanup.
Loop for up until all gThreadActive[] become clear or the clock runs out, whichever comes first.
If you use semaphores, use a single gThreadActive parameter and merely clear the bit!
LOCK();
gThreadActive ^= 1 << idx;
UNLOCK();
wildgoose
Practically a Posting Shark
896 posts since Jun 2009
Reputation Points: 546
Solved Threads: 99
I don't understand what's so difficult about thread timing. If you want the thread to quit after a specified amount of time, then just compare current time with original thread entry time and exit when that difference is greater than some pre-determined amount of time.
Ancient Dragon
Retired & Loving It
30,049 posts since Aug 2005
Reputation Points: 5,662
Solved Threads: 2,343
Ancient Dragon
Retired & Loving It
30,049 posts since Aug 2005
Reputation Points: 5,662
Solved Threads: 2,343