Community
cancel
Showing results for 
Search instead for 
Did you mean: 
kpatella
Beginner
19 Views

Getting Time Usage out of threads

Hi I'm working on a game where we have a background loading thread outside of the main game loop. I have gotten rid of all the lock problems between threads, but it still seems to get hitches when we're loading large chunks of data, but I can't find any other stalls. When I run Multi-Core it runs pretty smoothly, but then I shut off Multi-Core in my Bios and I noticed much bigger spikes. If I run at a lower priority it helps alot but then it takes too long to load the data in a 3second load at normal priority is taking 20seconds at below-normal. We are using Win32 threads. Is there a way for me to track the time Windows is spending in each thread that way I could see if windows is in the background thread for 200ms before switching back to the main thread?


Thanks,
Keith
0 Kudos
3 Replies
jimdempseyatthecove
Black Belt
19 Views

It sounds like you need to create two Mutex objects. In IVF (I will let you convert to CPP)

integer(HANDLE) :: DataReady = NULL
integer(HANDLE) :: DataConsumed = NULL
...

subroutine IOthread
DataReady = CreateMutex(NULL, TRUE, NULL)
do while(.true.)
if(.not. ReadData()) exit
if(ReleaseMutex(DataReady) .eq. 0) call error('??')
do while(DataConsumed .eq. NULL)
sleep(1) ! Other thread not yet initialized
end do
if(WaitForSingleObject(DataConsumed, 5000) .ne. 0) call error('??')
if(ReleaseMutex(DataConsumed) .eq. 0) call error('??')
end do
end subroutine IOthread

subroutine ComputeThread
DataConsumed = CreateMutex(NULL, TRUE, NULL)
do while(.true.)
do while(DataReady .eq. NULL)
sleep(1) ! Other thread not yet initialized
end do
if(WaitForSingleObject(DataReady, 5000) .ne. 0) call error('??')
if(ReleaseMutex(DataReady) .eq. 0) call error('??')
callCopyData
if(ReleaseMutex(DataConsumed) .eq. 0) call error('??')
call ProcessData
end do
end subroutine ComputeThread

Or something to the effect.

Also look at CreateEvent. This can be used similar to the mutex but you can have the event created as AutoReset. This could eliminate two ReleaseMutex. Although programming the AutoReset would be simpler, the Mutex I believe has less overhead.

Jim Dempsey

Intel_C_Intel
Employee
19 Views

That sounds for me as if you do not need help in thread safe code, but in a proper info function reporting user/kernel/real time consumptions for your running threads.

Under Win32, just take "GetThreadTimes" ... there's also a "GetProcessTimes" for accounting every horse in the stable.

I'm currently in a similar situation, developing some service concept under Win32 (VC++ has just thebest GUI), but the result has to work on "adult systems" and I fail to find an equivalent for pthread implementations. Theres just the standard "times()" which does not care for threads at all and reports process times. It's not important, but I'd like to have the ressource usage of each service thread for getting hints for the workload of each service type.

Does anybody have an idea ?

jimdempseyatthecove
Black Belt
19 Views

On a Windows platform I conditionaly compile in my own timing code using QueryPerformanceCounter and QueryPerformanceFrequency. Alternately, you can use statistical sampling of runtime by use of thread profiling tools such as Intel's VTune, AMD's CodeAnalyst, et. al.

From your description of the problem it sounds like you have the Bart Simpson on a car trip problem: too much "Are we there yet, are we there yet". i.e. in the single core configuration, the data consumer of the disk I/O is likely burning up too much time checking an I/O done flag. Thread profiling can easily identify this situation. The correction for this is to change the communication method between threads.

1) Using event in lieu of "spin wait" loops.
2) Reducing spin count counts (in appropriate places)
3) In wait for I/O loop insert appropriate "pause"

Jim Dempsey