Announcement

Collapse
No announcement yet.

Critical Section -> CPU overload

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

  • Critical Section -> CPU overload

    Hi,

    I found something strange in the tests that we are doing on our dlls concerning critical sections and CPU load.
    Before we go on, I just want to make sure this is 'normal'. It seems strange...

    As soon as I use critical section, the CPU goes directly to 100%. I know from more general tests (with more code) that CPU load is (very likely) one of the reasons that the amount of users that can be handled simulatious is low.

    Configuration:
    Server: NT4, SP6, IIS4
    running a simple ASP page that creates an ActiveX object (VB ActiveX Dll, apartment-threaded).
    The ActiveX is merely the web-interface for the PB Dll. It calls a function.

    Test machine: NT4, SP6
    running WCAT using 200 clients simulatious, no delay, 1.5 min.


    Tests (description is info on PB Dll actions):

    Test1: no LibMain, initialize vars
    Test2: addition: add LibMain
    Test3: addition: LibMain declares global critical section and initializes SQL Tools
    Test4: addition: global array StmtNr() is added with function to fill it based on the incoming request.
    Function is called: changes global data, so the critical section is used.


    Results:
    CPU Page results
    Test1 2% 1600
    Test2 2% 1600
    Test3 3% 1600
    Test4 100% 1600

    The page results are the same but CPU maxes out for the full 1.5 minute. When adding more code, the test dlls using the critical section provide poorer results than the onces that don't use it (using the same code of course).

    I this normal, or am I doing something wrong?

    Hope someone can help.

    Regards
    Jeroen Brouwers


    ------------------

  • #2
    How large is the global array you added and filled? What is taking the cpu time - did you use GetTickCount() to time the new code to see where the CPU is being exercised the most? A critical section is not going to increase CPU utilization noticably if at all.
    Can you post snippets or pseudocode to permit better visualization of what is going on inside the walls of the critical section?

    [This message has been edited by Ron Pierce (edited June 16, 2001).]

    Comment


    • #3
      Ron, thanks for the quick response.

      The global array is just storing number. I don't have the code at hand but it looks something like this:

      Code:
      GLOBAL StmtNrs() as DOUBLE        ' holds the unique statement number for each thread.
      
      FUNCTION STMTADD(StmrNr as double, Code as double) AS LONG
      
          FUNCTION = 0
          ON ERROR GOTO ADD_ERROR
      
          EnterCriticalSection CS1        ' declared globally in LibMain
      
          'add
          IF Code = 1 then
              If UBOUND(StmtNrS) > -1 THEN
                  REDIM StmtNrs(0)
                  StmtNrs(0) = 1
              Else
                  StmtNr = StmtNrs(Ubound(StmtNrs) ) + 2
                  REDIM PRESERVE StmtNrs(Ubound(StmtNrs) + 1)
                  StmtNrs(Ubound(StmtNrs) ) = StmtNr
      
              end if
      
          ' delete
          ELSEIF Code = 2
              for i = 0 To Ubound(StmtNrs)
                  if StmtNrs(i) = StmtNr Then
                      StmtNrs(i) = 0
                      exit for
                  end if
              next i
      
              ' check for possible delete
              for i = Ubound(StmtNrs) to 0 Step -1
                  if StmtNrs(i) > 0 Then
                      REDIM PRESERVE StmtNrs(i + 1)
                      exit for
                  end if
              next i
          END IF
      
          LeaveCriticalSection CS1
          FUNCTION = 1
          EXIT FUNCTION
      
      ADD_ERROR:
          FUNCTION = 0
          ON ERROR RESUME NEXT
          LeaveCriticalSection CS1
          EXIT FUNCTION
      END FUNCTION
      The function that is the incoming function declares some UDT local, initialises them, and filles the partially with set values. Then, this function is called. The return value of StmtNr is stored in the UDT.
      That's it.

      I'll have to look into TickCount (never used that before).

      I hope this already helps.

      Greetings
      Jeroen


      ------------------

      Comment


      • #4
        Are you creating threads which call the function in a dll which uses the critical section? Why are you using a critical section?

        Thanks,
        Ron

        Comment


        • #5
          Hi Ron,

          I don't understand exactly what you mean..

          The ASP page has some code:
          Code:
              Set ActX = CreateObject("AiSE.CAiSE")
              result = ActX.Entry(input, output1, output2, ID)
          The ActiveX dll (named AiSE.dll, with the class CAiSE) has the function Entry :
          Code:
          Public Function Entry(input, output1, output2, ID) as long
          
              Dim UDT1 as MY_UDT
              UDT1.Input = trim$(input)
              UDT1.UserID = trim$(ID)
          
              result& = MYDLL_ENTRY(UDT1)
          
              Output1 = trim$(UDT1.Output1)
              Output2 = trim$(UDT1.Output2)
              ID = trim$(UDT1.UserID)
          
          end function
          and a Module that declares the MY_UDT and the PB Dll function:
          DECLARE FUNCTION MYDLL_ENTRY Lib "AiSE1.DLL" (UDT1 AS MY_UDT) AS LONG

          The PB DLL has the function MYDLL_ENTRY:
          Code:
          FUNCTION MYDLL_ENTRY(UDT1 as MY_UDT) EXPORT AS LONG
          
              LOCAL Internal AS INTERNALINFO ' a UDT
          
              ' do some actions: fill Internal with general values, etc
              ' and then:
              local St as Double
              result& = StmtAdd(St, 1)    ' get a unique statement number based on a global array holding the statement numbers
              Internal.StmtNr = St
          
              ' do some action involving Database action using the Internal.StmtNr as statement number
          
              ' at the end:
              result& = StmtAdd(Internal.StmtNr, 2)    ' clear the statement number array, i.e. release the statement number for other threads
          
          END FUNCTION
          In my tests, I don't even use the statement number yet. There's no database connectivity what so ever. It's just testing what happens when reading memory.
          Because I link the PB Dlls to a ActiveX which is linked to an Active Server Page, it has to be thread-safe: each incoming request is a thread. So my global array has to be protected when changing it using Critical Section.
          At least, that's how I understand it. Maybe I wrong....

          Hope this answers your question. If not, I'll be glad to specify.

          Greetings
          Jeroen


          ------------------


          [This message has been edited by jeroen brouwers (edited June 17, 2001).]

          Comment


          • #6
            I am at a loss here. The PB code looks fine. It might be a VB thing. Remember, VB is not thread safe. Although an activex dll/exe is a viable means for VB to use multiple threads, when one of the instantiations starts playing with win32 thread synchronization functions, the results might not be pretty.

            Comment

            Working...
            X