Announcement

Collapse
No announcement yet.

Performance Speed on WinXP

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Michael Mattias
    replied
    .. problems related to context-switching derive from parallel (outside) applications
    Those aren't problems, that's what Windows is designed to do... provide multi-tasking.

    BTW, setting the priority is system-wide, not just relative to other threads of your application. If some other application has set its priority above "normal" that's a problem with the other software.

    Also, Windows DOES give more time to the thread owning the current active Window. (Buried in the doc for the SetActiveWindow function).

    I have said many many times optimization is always application-specific. If you have some application giving you difficulty, the first step is to use the PROFILE function (see in compiler's help file) to identify the procedures taking the most time. Then you can put your effort into optimizing the true "time-hogs" and not waste time tinkering around the margins.

    Before you start playing with system priorities, you need to take a close look at your application and make sure your own house is in order.



    MCM
    Last edited by Michael Mattias; 29 Feb 2008, 09:01 AM.

    Leave a comment:


  • Michael Mattias
    replied
    the core answer unless someone can correct me is...test on multiple machines, and a number you can live with
    Code:
      === USER OPTIONS===
       User Display name  [John Q Public               ]
       Loop Delay           [    ]
    
     ===================

    Leave a comment:


  • Chris Boss
    replied
    The book is:

    Multithreading Applications in Win32
    by Jim Beveridge and Robert Wiener
    Published by Addison Wesley Developers Press
    Copyright 1997

    Here it is on Amazon:

    http://www.amazon.com/Multithreading...4260974&sr=1-1

    Leave a comment:


  • Brian Chirgwin
    replied
    Originally posted by Chris Boss View Post
    First thing I lreaned about threads (from a very good book by an expert) is don't modify the GUI from worker threads.
    Chris,

    Do you remember the book? I'd like to pick it up if I don't have it.

    Brian

    Leave a comment:


  • Paul Dixon
    replied
    Heinz,
    Is the execution- speed of "sleep 1" ("sleep 0" seems not to work) differently executed on different XP-machines? (This had been discussed in other threads here! But where?)
    Yes. Timeslices vary. The usual starting time slice is around 15 to 16ms (it's acually 15.625, that's 1/64th of a second, but is then averaged to the nearest whole millisecond).
    If you SLEEP 0 then you give up your timeslice immediately but return immediately if no other process wants it.
    If you SLEEP 1 then you give up your timeslice immediately but even if nothing else wants it you will not return for 16 msec. That time will then go to CPU IDLE time.

    Certain other processes can change this. The timeslices can drop to 1ms each under certain circumstances when other, unrelated programs, do things.
    To see what timeslice you have, write a program something like this:

    Code:
    DECLARE FUNCTION QueryPerformanceFrequency LIB "KERNEL32.DLL" ALIAS "QueryPerformanceFrequency" (lpFrequency AS QUAD) AS LONG
    DECLARE FUNCTION QueryPerformanceCounter   LIB "KERNEL32.DLL" ALIAS "QueryPerformanceCounter" (lpPerformanceCount AS QUAD) AS LONG
    
    FUNCTION PBMAIN () AS LONG
    
    LOCAL freq, count0, count1 AS QUAD
    
    QueryPerformanceFrequency freq   'Get timer frequency.
    
    QueryPerformanceCounter count0   'read the timer at the start of the test
    
    DO
        SLEEP 1
        count0=count1
        QueryPerformanceCounter count1
        LOCATE 1,1
        PRINT FORMAT$(1000*(count1-count0)/freq,"######0.000");"msec              "  'print the elapsed time
        
    LOOP UNTIL INSTAT
    
    END FUNCTION
    As you increase the SLEEP value from 1 to 20 in steps of 1ms you'll see what happens to the actual SLEEP time you get.

    Now, while that program is running with the SLEEP set to 1msec, try running the following code and look at what happens to the SLEEP time in the first program.

    Code:
    REM use a TIMER TO 0.001s
    
    $INCLUDE "WIN32API.INC"
    DECLARE FUNCTION test( BYVAL uID AS LONG, BYVAL uMsg AS LONG, _
                             BYVAL dwUser AS LONG, BYVAL dw1 AS LONG, BYVAL dw2 AS LONG) AS LONG
    
    GLOBAL COUNT AS LONG
    
    FUNCTION WINMAIN (BYVAL hInstance     AS LONG, _
                      BYVAL hPrevInstance AS LONG, _
                      BYVAL lpCmdLine           AS ASCIIZ PTR, _
                      BYVAL iCmdShow      AS LONG) AS LONG
    
    'start the timer
    '1=milliseconds between triggers, 0=maximum timer resolution, test=the routine to call
    TimerHandle& = timeSetEvent ( BYVAL 1, BYVAL 0, CODEPTR(test), BYVAL 0&, BYVAL %TIME_PERIODIC)
    
    PRINT "press a key to end."
    DO
       LOCATE 10,10
       PRINT "Time=";FORMAT$(count&/1000,"#######.###");"secs."
       SLEEP 1
       LOOP UNTIL INSTAT
    
       timeKillEvent TimerHandle&
    
    END FUNCTION
    
    FUNCTION test ( BYVAL uID AS LONG, BYVAL uMsg AS LONG, _
                            BYVAL dwUser AS LONG, BYVAL dw1 AS LONG, BYVAL dw2 AS LONG) AS LONG
    'this is the routine that is run everytime the timer triggers
    
          INCR COUNT
    END FUNCTION
    Paul.

    Leave a comment:


  • Cliff Nichols
    replied
    Heinz,
    If you are asking what I think you are asking.
    "How many threads, at what priority are too much?"

    Unfortunately the answer is "It Depends"

    A thought I had was if all priorities are equal, then if I read somewhere was correct that each thread gets 20ms to complete or release then the question is...each thread in Windows? or does my process = a 20ms time slice and I delegate to each thread I created?

    Sure you could have a tight loop (no sleeps) but then the CPU strikes depending on how long your process has its time slice, so you have to carefully balance how intensive "Background" is vs god knows how many other apps begging for the time slice you do not give up (whether you are finished or not)

    the core answer unless someone can correct me is...test on multiple machines, and a number you can live with that you give up your time-slice to other processes

    Leave a comment:


  • Heinz Grandjean
    replied
    Good evening community!

    Mr. Mattias said:
    Poor application performance is almost always caused not by the hardware, not by the operating system, not by the compiler, and not even by inferior technique: it's caused by poor design.

    My answer: Oh,yes, that's the reason, why I'm asking for help.

    Additionally:
    Otherwise I feel guilty, because if it really is a "background task" why the heck am I giving it the same priority as my user interface?

    My answer: This is an emotional argument and quite logical, if the technical
    priorities are clear; but - on my side looking for the technical background - it's still emotional. But i will try this too.

    Additionally:
    You can use SetThreadPriority() against the handle returned by THREAD CREATE. You have to do it that way because my three-year old new feature suggestion for a THREAD SET PRIORITY 'native' feature is apparently still 'under consideration.'

    This argument discusses priority inside an application and it's well underlined by Mr. Mattias' professionality.
    But I have learned just in that thread here, that problems related to context-switching derive from parallel (outside) applications....

    I would be interested - in all respect - how to handle the quantity of sleep statements inside the two parallel -executing threads of "my" application in relationship to all the other "enemy"-CPU's loads.
    Is there a way to find out proper values?

    Greetings and thanks for help,

    Heinz Grandjean

    Leave a comment:


  • Michael Mattias
    replied
    >I am using the default priority for the worker threads as well

    In my production apps I always set the priority down for worker threads.*

    Otherwise I feel guilty, because if it really is a "background task" why the heck am I giving it the same priority as my user interface?

    * You can use SetThreadPriority() against the handle returned by THREAD CREATE. You have to do it that way because my three-year old new feature suggestion for a THREAD SET PRIORITY 'native' feature is apparently still 'under consideration.'

    Leave a comment:


  • Chris Boss
    replied
    I only have one Vista machine which I tested this on.

    I am using the default priority for the worker threads as well.

    Leave a comment:


  • Michael Mattias
    replied
    How could I have forgotten this?

    Poor application performance is almost always caused not by the hardware, not by the operating system, not by the compiler, and not even by inferior technique: it's caused by poor design.


    MCM

    Leave a comment:


  • Michael Mattias
    replied
    >Would it be possible, to stop other background-running

    In theory, sure.

    However, that would be on your way to the unemployment line.

    You "can" give your own program essentially exclusive use of the processor by setting the thread priority to a large value. But the caution in the doc is a wise one:

    When manipulating priorities, be very careful to ensure that a high-priority thread does not consume all of the available CPU time. A thread with a base priority level above 11 interferes with the normal operation of the operating system. Using REALTIME_PRIORITY_CLASS may cause disk caches to not flush, hang the mouse, and so on.

    Leave a comment:


  • Cliff Nichols
    replied
    HEH good luck,

    Sorry...Knee-Jerk reaction :laugh:

    Just out of curiosity Chris, is Vista home working differently from system to system as far as you can tell? (I only have a small sample to work from, but sure there are differences from flavor to flavor of Vista)

    Leave a comment:


  • Heinz Grandjean
    replied
    Yes, thank You, I understand.
    Would it be possible, to stop other background-running. The question could be: How to identify non friendly threads of other programms and how to set them to sleep until the own programm's realtime loops have finished.
    Maybe a certain: Shut down everybody around during my own, most important execution time???

    Leave a comment:


  • Chris Boss
    replied
    There is one thing about Threads to consider and that is their priority. There are multiple levels of priority, starting with the primary thread (process) and then the worker threads.

    If the priorities are set differently because of the operating system, then you will see speed differences.

    Also consider that Windows has become a hog because of all sorts of services running in the background. It is likely worse on Vista.

    Because of this, different PC's may have different software loaded which is running in the background and this will significantly impact the speed of threads.

    Unless two PC's are absolutely identical (hardware and software) you can not guarantee the same speed for running an app or its threads.

    Leave a comment:


  • Chris Boss
    replied
    Using SLEEP can be tricky, especially with threads.

    While I haven't come across problems with XP on different systems yet, there is a problem with Vista.

    I have a simple sample program which runs well using two worker threads communicating to the main GUI thread (primary thread) updating a graphic control (Canvas) many times a second. It draws a simple animated graphic in each control.

    It works fine on XP Home, but on Vista Home basic the threads don't run equally. One thread slows down terribly. Vista is obviously handling the switching between threads differently than does XP.

    Maybe XP runs differently because of the hardware or something on different systems. I don't know, but it is possible.

    Leave a comment:


  • Heinz Grandjean
    replied
    Apologizes for late answering and many thanks for the help.

    Paradoxically I did all the thread-managing that You suggested in Your answers. I have learned a lot from the forum and carefully read Beverigde/Wiener's guide to threads. That confirms me that the problem seems to lay elsewhere. I think I found it: To garantee proper context-switching between the both worker-threads and the main-dialog, the first statement in each thread's "do loop" -structure was "Sleep 1".
    I changed the threads executing the "sleep 1" statemant only once in 100 circles and now everything is very fast, even on slow -machines.
    Four questions arise from that:
    1) Is the execution- speed of "sleep 1" ("sleep 0" seems not to work) differently executed on different XP-machines? (This had been discussed in other threads here! But where?)
    2) Could the bespoked delay depend on the context-switching overhang?
    3) Is context-switching executed differently on different XP-machines?
    4) Is there a way to gain control about the context-switching -speed?

    Thanks and greetings from Germany
    Heinz Grandjean

    Leave a comment:


  • Michael Mattias
    replied
    You can get around the thread switch by POSTING a message to your main window and letting the GUI thread handle the update when the GUI thread already has the time slice...

    Code:
    %PWM_UPDATE_ICON = %WM_USER + 1 
    
    FUNCTION MainWindowProc ...
    
         CASE %PWM_UPDATE_ICON 
         do it. 
         You can use lparam and wparam to pass info 
    
    
    FUNCTION THreadFunction...
    
       DO WHILE...
          INCR nLoop 
          IF nLoop MOD 60 = 0 THEN
              PostMessage hWndMain, %PWM_UPDATE_ICON, somewParam, someLparam
          END IF 
         ....  yadda, yadda.
    Now there is no forced thread switching... the system 'catches up' whenever Windows goes back to service the GUI thread.


    MCM

    Leave a comment:


  • Chris Boss
    replied
    First thing I lreaned about threads (from a very good book by an expert) is don't modify the GUI from worker threads.

    The books author referred to the main thread (processes primary thread) as the GUI thread, where all GUI code should be. He recommended avoiding modifying the GUI from worker threads, since it adds a lot of overhead which can slow things down.

    The thing about Windows is that when GUI elements are created (dialogs, windows, controls), they must be accessed from the same thread. This means that when a worker thread makes call to an API function or message, which affects a GUI element (window), Windows must do a context switch and switch to the windows creation thread, act on the window and then swap back to the worker thread.

    Likely the speed problems you have may be the result of this situation.

    Another consideration is how often a GUI object is modified. If a loop runs 60 times per second and each loop sets a GUI objects state, this can slow things down a lot. One technique that helps is to only update the GUI elements at loner intervals. For example, by changing code to only modify the GUI say every 10th of a second (for your 60 intervals/second loop, this would be once every six intervals) you lessen the oberhead needed to modify the GUI. The end user sees no difference between changes are made quick enough for the human eye, but slow enough so they don't notice it.

    Leave a comment:


  • Heinz Grandjean
    started a topic Performance Speed on WinXP

    Performance Speed on WinXP

    Good evening, community.

    I fear that my question is fairly global. But that is exactly the reason why I don't know where to search for the problem.
    I have a PBWin created application that manages two worker-threads permanently during runtime.
    Both threads change their individual icon in the main-window's statusbar always after 60 loops.
    The synchronisation is done by using Window's CRITICALSECTION.
    Normally the programm performes very fast, indicated by the fast change of the thread's icons, mentioned above.
    But on some XP-machines the application works with reasonable reduced -speed. The speed is alway steady: either fast or slow on some machines.
    This seems not to be related to the CPU-speed. I have one user with a
    2.1 GHZ-CPU, but the application performes very slowly.
    I'm using GFX-Tools, but don't know if there is a relationship to the question.
    During runtime there should be no contact to the main-disk, because all data is loaded before into the processor.
    The problem doesn't occour on WIn98 and on Vista as far as I have seen.
    Interesting: On one XP-machine the programme starts to hurry, if one opens IE; after closing IE, it again creeps.
    Additionally I should mention, that the running programme only uses 1% of CPU-capacity.
    Where do I have to start searching?

    Thanks for help and greetings from Germany
    Heinz Grandjean
    Last edited by Heinz Grandjean; 25 Feb 2008, 04:48 PM.
Working...
X