Announcement

Collapse
No announcement yet.

REGISTER Gains Less Than Expected?

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

  • Christopher Carroll
    replied
    Hi Gary

    I read that sentence as meaning that the compiler can only assign a variable to a register if it is of the expected type (i.e. integer class or extended-precision float; but not a string, for example). Finding all the permutations of information in the help can be a challenge! Maybe we all need eidetic memories.

    A small test, with 3 integer-class variables:

    Code:
    Function PbMain() As Long
        Register x As Long
        Register y As Long
        Local z As Long
        z = 1
    End Function
    decompiles the same as
    Code:
    Function PbMain() As Long
        Local x As Long
        Local y As Long
        Local z As Long
        z = 1
    End Function
    i.e.
    Code:
    ...
    XOR ESI,ESI                     ; x stored in ESI
    XOR EDI,EDI                     ; y stored in EDI
    MOV DWORD PTR SS:[EBP-A4],1     ; z = 1. z stored in application memory 
    ...
    And with just 2 integer-class variables:
    Code:
    Function PbMain() As Long
        Local x As Long
        Local y As Long
        y = 1
    End Function
    this decompiles as:
    Code:
    ...
    XOR ESI,ESI                     ; x stored in ESI
    XOR EDI,EDI                     ; y stored in EDI
    MOV EDI,1                       ; y = 1
    ...

    Leave a comment:


  • Gary Beene
    replied
    Hi Christopher,

    Whoops, it does say how it picks. My brain must have stopped with the word "attempt", taking that to mean there's no guarantee how REGISTER would be applied.

    ... the compiler will attempt to choose for you
    Looking at the second sentence you quoted from Help, I probably wouldn't have used the sentence with the word "attempt" in it, I'd have just stated the compiler default action, qualified with some version of "if any such integer-class variables have been declared".

    Thanks for pointing out the Help comment that I went blank on.

    Leave a comment:


  • Christopher Carroll
    replied
    Help doesn't say exactly how variables are picked as Register variables, so the only way to guarantee selection is to do it manually.
    In the help:
    -- Optimizing your code; Use Register Variables; para 3:
    The REGISTER statement allows you to choose which variables will be classified as Register variables. If you do not make the choice in a particular procedure, the compiler will attempt to choose for you. By default, the compiler will always assign the first two integer-class local variables available.

    Leave a comment:


  • Gary Beene
    replied
    Ok, I tested again.

    If I do not use #Register None, then the Sub runs just as fast as when I do use #Register None - provided I let the compiler pick i,j as the Register variables. In this example, the ONLY variables were i,j so there was no doubt about which variables would be selected.

    If I use #Register None, then create and use Register on other variables (not i,j, the loop variables), then the Sub runs more slowly.

    Help doesn't say exactly how variables are picked as Register variables, so the only way to guarantee selection is to do it manually.

    Thanks Paul, for the clarification.

    Leave a comment:


  • Gary Beene
    replied
    So, to see the real difference I need to make sure i,j are Register'd in one version, and not Register'd in the other.

    I can do that by making unused variables r,s (for example) and apply Register to them.

    Can I know which variable was selected as a register variable, when I allow the compiler to decide?

    Leave a comment:


  • Paul Dixon
    replied
    Gary,
    Code:
    Sub MySub_Slow
        Local i As Long, j As Long
    Without #REGISTER NONE the compiler will allocate the register variables for you and it will usually do the first suitable variables it comes across.
    In your example that would be i and j so even though you don't explicitly declare tham as register variables they will be set by the compiler as register variables.

    Paul.

    Leave a comment:


  • Gary Beene
    replied
    Oh, I see! I missed the compiler command:

    Code:
    #Register None
    It must be used for REGISTER to be applied.

    With #Register None in it, there was a 50% reduction in time to complete the loop.

    Note that this big an increase was possible because there was no real content within the loops. The more code within the nested loops, the less of a % impact there will be.

    With nothing in the loops, the slow version took 2.9 seconds, whereas the REGISTER version took 0.5 seconds. This shows where the speed advantage is seen.
    Last edited by Gary Beene; 11 Nov 2009, 08:55 PM.

    Leave a comment:


  • Gary Beene
    started a topic REGISTER Gains Less Than Expected?

    REGISTER Gains Less Than Expected?

    I made this simple test - calling a function which simply has nested do loops.

    In one version, Local is used to declare loop variables i,j. In the second version, REGISTER is used to declare the loop variables.

    When timed, both give approximately the same answer. Based on what I read in Help, I was expecting a very noticeable difference. Were my expectations too high? Or have I used REGISTER incorrectly?


    Code:
    #Compile Exe
    #Dim All
    #Include "win32api.inc"
    
    Function PBMain() As Long
        Local hDlg As Dword
        Dialog New Pixels, 0, "Button Test",300,300,200,200, %WS_OverlappedWindow To hDlg
        Control Add Button, hDlg, 100,"Push", 50,10,100,20
        Dialog Show Modal hDlg Call DlgProc
    End Function
    
    CallBack Function DlgProc() As Long
       If Cb.Msg = %WM_Command And Cb.Ctl = 100 And Cb.CtlMsg = %BN_Clicked Then
          Dim iStart As Long, iEnd As Long, Result As String
          iStart = GetTickCount
          MySub_Slow
          iEnd = GetTickCount
          MsgBox "Slow: " + Format$((iEnd - iStart)/1000,3) & " seconds"
    
          iStart = GetTickCount
          MySub_Fast
          iEnd = GetTickCount
          MsgBox "Fast: " + Format$((iEnd - iStart)/1000,3) & " seconds"
       End If
    End Function
    
    Sub MySub_Slow
        Local i As Long, j As Long
        Local x As Single
        For i = 1 To 1000000
            For j = 1 To 2000
               x = i
            Next j
        Next i
    End Sub
    
    Sub MySub_Fast
        Register i As Long, j As Long
        Local x As Single
        For i = 1 To 1000000
            For j = 1 To 2000
               x = i
            Next j
        Next i
    End Sub
Working...
X