Community
cancel
Showing results for 
Search instead for 
Did you mean: 
ramasubbu_sk
Beginner
53 Views

Reducing the thread/loop execution speed.

Hi all,

I hope this is the right forum to execute. My Stress tool has 4 threads running, each thread does operation A,B,C,D respectively in a loop.

When I run the tool, the CPU utilization goes to 100%. I want to reduce the speed of the total process by 50%.

If I add Sleep(1) [http://msdn2.microsoft.com/en-us/library/ms686298.aspx] in each thread then the execution speed does down drastically.

If I add sleep(1) in only one or few threads then the remaining thread takes more priority and still the CPU goes to 100%.

Is there any good API in Windows that gives me such functionality ?

Thanks in Advance

-RamaSubbu SK

0 Kudos
2 Replies
kalbr88
Beginner
53 Views

It would be nice to know the details of your loop. Otherwise the group will just speculate as to possible solutions. If you are inserting a Sleep(1) on every iteration, then that could be slowing things too much. You could write it so a Sleep occurs periodically but would have to be careful on how the branch performs. Say for example you have 1000 iterations, you could break it into two loops of 500 each with a Sleep in between. Also, I should point out that Sleep(1) may not sleep for only 1 ms. It actually be 10-15 ms depending on the interrupt timer. You could use the timeBeginPeriod(1)/timeEndPeriod(1) around your code, but note that can cause the whole system to be less efficient due to increased timer rate. So, it's better to know that it can take longer and account for that.

Another possibility, have you tried using a pause instruction instead? There is an intrinsic you can use, _mm_pause();

There are various ways you could use less CPU in the code. There's not a Windows API to scale operating code by a factor say by 50%. But you could run a profiler (such as VTune) to see what the hotspot in the code is and possibly reduce that load by changing the way the instructions are performed (replacing with SSE, unrolling loop, etc.). There's many good suggestions in various white papers available. For example:
A Methodology for Threading Serial Applications - http://www.intel.com/cd/ids/developer/asmo-na/eng/219349.htm

If the reason you need to reduce the load is to allow other things to run, you could simply try changing the thread priority so that it doesn't slow the entire system down. Like using SetThreadPriority with THREAD_PRIORITY_BELOW_NORMAL.


Good luck,

Keith
jimdempseyatthecove
Black Belt
53 Views

>> My Stress tool has 4 threads running... If I add sleep(1) in only one or few threads then the remaining thread takes more priority and still the CPU goes to 100%.

Then this would imply that the system you are running on has fewer than four processors. It would help us if you disclose the processor(s) and other system information.

Your intentions for the speed reduction is also not disclosed. Is the 50% utilization for thermal management, is it for making time available for other processes, or is it for some other reason?

Keith's suggestion of using the pause instruction will help in thermal management but it will not help with % utilization. Think of the pause instructionas a long instruction time using low power and low memory bandwidth requirementsfor the duration of the instruction.

If you want to make time available to run other applications (e.g. burn a CD) but not interfere with the performance of your application (Stress tool now, your application later) then consider inserting Sleep(0) (C function, or SLEEPQQ Fortran function) at various positions within your application (stress test now, application later). Sleep of 0ms means release remaining scheduled time slot. i.e. if something else needs to run it will have a better opportunity to run.

!$OMP PARALLEL DO
DO I,1,LIMIT
CALL A
CALL SLEEPQQ(0)
CALLB
CALL SLEEPQQ(0)
CALLC
CALL SLEEPQQ(0)
CALLD
CALL SLEEPQQ(0)
END DO
!$OMP END PARALLEL DO

If your stress tests (A,B,C,D) run sufficiently long then consider inserting the Sleep(0) within the subroutine (every n iterations as Keith suggested).

If you really want to consume at most 50% of the available CPU time AND if your system has more than one processing element (Core or Processor) then consider restricting the number of threads to 1/2 the available processing elements. Note, Hyper Threading systems show 2 processing elements per processor but where one of the processing elements might consume 70%-95% of available capacity. If you have HT then you may need the Sleeps. Try the following if you have more than one processing element.

CALL OMP_SET_NUM_THREADS( &
& MAX(1, OMP_GET_NUM_PROCS()/2)
!$OMP PARALLEL DO
DO I,1,LIMIT
CALL A
CALLB
CALLC
CALLD
END DO
!$OMP END PARALLEL DO

Jim Dempsey

Reply