Announcement

Collapse
No announcement yet.

access on big array

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

  • access on big array

    Why is the access to DWORD-VarPtr three times slower (as LONG-VarPtr)?
    Is there a faster way for access on big array?

    Code:
    #COMPILE EXE
    #DIM ALL
    
    
    FUNCTION PBMAIN () AS LONG
    LOCAL i          AS LONG
    LOCAL a1         AS LONG
    LOCAL a2         AS DWORD
    LOCAL t1, t2, t3 AS SINGLE
    
        DIM arr(500000000) AS BYTE
    
        [B]' a1 --> long --> is speedy[/B]
        a1 = VARPTR(arr(LBOUND(arr)))
        t1 = TIMER
        FOR i = LBOUND(arr) TO UBOUND(arr)
            POKE a1, i+1
            INCR a1
        NEXT i
        t1 = TIMER - t1
    
        [B]' a2 --> dword --> is slower[/B]
        a2 = VARPTR(arr(LBOUND(arr)))
        t2 = TIMER
        FOR i = LBOUND(arr) TO UBOUND(arr)
            POKE a2, i+1
            INCR a2
        NEXT i
        t2 = TIMER - t2
        
        [B]' with array access --> is medium[/B]
        t3 = TIMER
        FOR i = LBOUND(arr) TO UBOUND(arr)
            arr(i) = i+1
        NEXT i
        t3 = TIMER - t3
    
        MSGBOX "1. Method:" + STR$(t1) + $CR+$CR + "2. Method:" + STR$(t2) + $CR+$CR + "3.Method:" + STR$(t3)
    END FUNCTION

  • #2
    The compiler (and the CPU/FPU) is optimized for the use of Long Integers. That's the preferred data type, whenever possible.

    Bob Zale
    PowerBASIC Inc.

    Comment


    • #3
      Not only that, but some versions of Windows give a performance boost to programs that have just been launched. Programs get more CPU cycles shortly after launch, then they are "throttled down"... so an overly-simple timing test may produce results that are biased toward the first test they perform.

      Benchmarking is tricky!

      -- Eric
      "Not my circus, not my monkeys."

      Comment


      • #4
        @Bob:
        I want to use the quick methode (with long pointer variable).

        What if, there VarPtr get a negative address value?

        Code:
        dim p as long
        dim test as byte
        ' Assumed: [B]test[/B] is saved on memory address 2,547,483,647
        
        p = varptr(test)
        ' VarPtr supplies -1,747,483,649
        
        POKE p, 65
        ' Is [B]POKE [I]-1747483649[/I], 65[/B] ok?
        Last edited by Bernhard Fomm; 10 Sep 2009, 02:35 PM.

        Comment


        • #5
          Pointers

          I would not immediately recommend the following as the code is more difficult to maintain. It is more confusing especially to someone that does not understand pointer arithmetic. On the other hand, it is a nice performance increase.

          Replace the MSGBOX in the original code with the following.

          Code:
              Local nLBound As Long
              Local nUBound As Long
              Local ptrDWRD As Dword Pointer
          
              t4 = Timer
              nLBound = LBound(arr)
              nUBound = UBound(arr)
              ptrDWRD = VarPtr(arr(nlBound))
          
              For i = nLBound To nUBound Step 4
                  ' Using a DWRD (4 bytes) add 1 to the high byte, add 2 to the second, 3 to the 3rd and 4 to the forth. 
                 ' In Decimal this equals 1609060 [IF I have done my math correct.]
                  
                  @ptrDWRD = i + 16909060 ' 0000 0001 + 0000 0010 + 0000 0011 + 0000 0100
                  
                  Incr ptrDWRD ' DWORD Pointer, jumps ahead a DWORD, 4 bytes
          
              Next i
              t4 = Timer - t4
          
              MsgBox "1. Method:" + Str$(t1) + $Cr+$Cr + "2. Method:" + Str$(t2) + $Cr+$Cr + "3.Method:" + Str$(t3) + $Cr+$Cr + "4.Method:" + Str$(t4)
              
          End Function

          Comment


          • #6
            Simple change might help....
            Code:
            LOCAL A2  AS BYTE PTR    <<<< CHANGE 
            '    ' a2 --> dword --> is slower
                a2 = VARPTR(arr(LBOUND(arr)))
                t2 = TIMER
                FOR i = LBOUND(arr) TO UBOUND(arr)
                    @a2 = i+1
                    INCR a2
                NEXT i
                t2 = TIMER - t2
            BTW, you do realize you are generating a numeric overflow here, right? (as soon as I>=255). You are also forcing type conversions, which takes time. (trying to POKE a DWORD into a byte? but not stepping up the poke address by four?)

            Granted this is test/demo code, but we see enough stuff here which does the same things and "bad results," "slow" or both is the result.

            MCM
            Michael Mattias
            Tal Systems (retired)
            Port Washington WI USA
            [email protected]
            http://www.talsystems.com

            Comment


            • #7
              Originally posted by Michael Mattias View Post
              Simple change might help....
              Code:
              LOCAL A2  AS BYTE PTR    <<<< CHANGE 
              '    ' a2 --> dword --> is slower
                  a2 = VARPTR(arr(LBOUND(arr)))
                  t2 = TIMER
                  FOR i = LBOUND(arr) TO UBOUND(arr)
                      @a2 = i+1
                      INCR a2
                  NEXT i
                  t2 = TIMER - t2
              This is as "slow" as the method number 2.
              This help not.

              Comment


              • #8
                My question is:

                Working POKE correctly with LONG-addresses (from -2 to +2GB)?
                What if, there VarPtr get a negative address value?

                POKE is working automatically with the entire DWORD address space (from 0 to +4GB)?
                Also when a LONG address variable is used?
                Last edited by Bernhard Fomm; 10 Sep 2009, 05:03 PM.

                Comment


                • #9
                  Maybe i am not up to this subject but varptr() returns a dword.
                  A dword is never negative.

                  This may all need to be changed in 64bits computing but then.. the compiler produces 32bit apps.
                  hellobasic

                  Comment


                  • #10
                    Hmm, i don't think i would this as you are doing.
                    There are two different ways:

                    1) Dim At ....
                    2) Pointer[index]

                    The 2nd was told was slower for some reason.
                    Both avoid the poke and may be faster..
                    At the end, some form of byte copying is done after all of course.
                    hellobasic

                    Comment


                    • #11
                      Originally posted by Edwin Knoppert View Post
                      Maybe i am not up to this subject but varptr() returns a dword.
                      A dword is never negative.
                      Yes.

                      But, when address-variable p is a long-variable?

                      What if VarPtr +2,500,000,000 (2.5GB!) there?
                      Then stand in p -1,700,000,000!

                      Code:
                      dim p as long
                      dim test as byte
                      [B]' Assumed: test is saved on memory address 2,547,483,647[/B]
                      
                      p = varptr(test)
                      [B]' VarPtr supplies -1,747,483,649[/B]
                      
                      POKE p, 65
                      ' Is [B]POKE -1747483649, 65[/B] ok?

                      Comment


                      • #12
                        Yes, you can do that safely.

                        Bob

                        Comment


                        • #13
                          LONG, DWORD, PTR... makes no difference as long as you are not doing arithmetic operations or comparisons. It's the same thirty-two bits.
                          Michael Mattias
                          Tal Systems (retired)
                          Port Washington WI USA
                          [email protected]
                          http://www.talsystems.com

                          Comment


                          • #14
                            Thanks all!

                            Another Question

                            POKE is working correctly even under the 64-Bit-Windows (with more as 4GB RAM)?
                            Or, It may cause any problems in the worst case?
                            Last edited by Bernhard Fomm; 11 Sep 2009, 01:35 PM.

                            Comment


                            • #15
                              I am sure you're under some kind of WOW32
                              hellobasic

                              Comment


                              • #16
                                POKE is working correctly even under the 64-Bit-Windows (with more as 4GB RAM)?
                                Or, It may cause any problems in the worst case?
                                The amount of physical memory does not matter.

                                32-bit applications run with virtual addresses in the range 0-0xFFFFFFFFF only, and everything you do in your application programs is done using only virtual addresses.

                                MCM
                                Michael Mattias
                                Tal Systems (retired)
                                Port Washington WI USA
                                [email protected]
                                http://www.talsystems.com

                                Comment


                                • #17
                                  Ahhh... Okay... Many Thanks!

                                  Comment

                                  Working...
                                  X