User Tools

Site Tools


accessing_20the_20fast_20sys_20interface

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

accessing_20the_20fast_20sys_20interface [2018/03/31 13:19]
127.0.0.1 external edit
accessing_20the_20fast_20sys_20interface [2018/04/14 20:32] (current)
richardrussell Added syntax highlighting
Line 1: Line 1:
 =====Accessing the fast SYS interface===== =====Accessing the fast SYS interface=====
  
-//by Jon Ripley, July 2006//\\ \\  The SYS statement allows you to call functions in the following DLLs //(Dynamic Link Libraries)//​ by name. Functions in all other DLLs must be called by their address in memory.\\ +//by Jon Ripley, July 2006//\\ \\  The SYS statement allows you to call functions in the following DLLs //(Dynamic Link Libraries)//​ by name. Functions in all other DLLs must be called by their address in memory.
  
   * ADVAPI32.DLL   * ADVAPI32.DLL
Line 11: Line 11:
   * USER32.DLL   * USER32.DLL
   * WINMM.DLL   * WINMM.DLL
-\\  The price for the convenience of calling functions in the above DLLs by name is speed. Calling a function by name is approximately 12 times slower than calling it by address. Where a function is called only a few times in a program this may not have much of an impact on the overall speed of a program. However, where a program makes extensive use of functions in the above DLLs, especially in tight loops, calling the functions by name instead of by address can have a significant performance cost.\\ \\ +  
 +The price for the convenience of calling functions in the above DLLs by name is speed. Calling a function by name is approximately 12 times slower than calling it by address. Where a function is called only a few times in a program this may not have much of an impact on the overall speed of a program. However, where a program makes extensive use of functions in the above DLLs, especially in tight loops, calling the functions by name instead of by address can have a significant performance cost. 
 ==== Finding the address ==== ==== Finding the address ====
-\\  ​To find the address of any function that can be called by name use the following routine:\\ + 
 +To find the address of any function that can be called by name use the following routine: 
 + 
 +<code bb4w>
         DEF FNSYS_NameToAddress(f$)         DEF FNSYS_NameToAddress(f$)
         LOCAL P%         LOCAL P%
Line 21: Line 26:
         ]         ]
         =P%!-4+P%         =P%!-4+P%
-Here **f$** is the name of the function. **FNSYS_NameToAddress** returns the address of the function. You should read the addresses of functions you will use in the initialisation routine of your program.\\ \\  The following example demonstrates using **FNSYS_NameToAddress**:​\\ +</​code>​ 
 + 
 +Here **f$** is the name of the function. **FNSYS_NameToAddress** returns the address of the function. You should read the addresses of functions you will use in the initialisation routine of your program.\\ \\  The following example demonstrates using **FNSYS_NameToAddress**:​ 
 + 
 +<code bb4w>
         REM Program initialisation         REM Program initialisation
         _sleep% = FNSYS_NameToAddress("​Sleep"​)         _sleep% = FNSYS_NameToAddress("​Sleep"​)
Line 29: Line 38:
           SYS _sleep%, 10           SYS _sleep%, 10
         UNTIL FALSE: REM Loop forever         UNTIL FALSE: REM Loop forever
-\\  ​Do not do the following, this is slower than calling a function by name:\\ +</​code>​ 
 + 
 +Do not do the following, this is slower than calling a function by name: 
 + 
 +<code bb4w>
           SYS FNSYS_NameToAddress("​Sleep"​),​ 10           SYS FNSYS_NameToAddress("​Sleep"​),​ 10
-\\ +</​code>​ 
 ==== Finding the address of BASIC I/O routines ==== ==== Finding the address of BASIC I/O routines ====
-\\ **FNSYS_NameToAddress** can be used to read the address of the BASIC I/O routines as listed in the [[http://​www.bbcbasic.co.uk/​bbcwin/​manual/​bbcwina.html#​basicio|Using BASIC input/​output]] section of the manual. To read the address of a BASIC I/O routine use code similar to the following:\\ \\ + 
 +**FNSYS_NameToAddress** can be used to read the address of the BASIC I/O routines as listed in the [[http://​www.bbcbasic.co.uk/​bbcwin/​manual/​bbcwina.html#​basicio|Using BASIC input/​output]] section of the manual. To read the address of a BASIC I/O routine use code similar to the following: 
 + 
 +<code bb4w>
         oswrch = FNSYS_NameToAddress("​oswrch"​)         oswrch = FNSYS_NameToAddress("​oswrch"​)
-Here we read the address of the **"​oswrch"​** routine and store it in the variable **oswrch**. Limited practical uses of this technique do exist.\\ \\ +</​code>​ 
 + 
 +Here we read the address of the **"​oswrch"​** routine and store it in the variable **oswrch**. Limited practical uses of this technique do exist. 
 ==== Proof ==== ==== Proof ====
-\\  ​To demonstrate that calling a function by pointer is significantly faster than calling the same function by name the following proof is included.\\ \\ + 
 +To demonstrate that calling a function by pointer is significantly faster than calling the same function by name the following proof is included. 
 + 
 +<code bb4w>
         REM SYS Timing Test         REM SYS Timing Test
         C%=1000000         C%=1000000
         REPEAT         REPEAT
-Here **C%** is set to the number of iterations for the timing loops.\\ \\  
           REM How long does an empty loop take?           REM How long does an empty loop take?
           T%=TIME           T%=TIME
Line 49: Line 71:
           O%=TIME - T%           O%=TIME - T%
           PRINT "Empty loop    : " ;(TIME - T%)/​100"​s"​           PRINT "Empty loop    : " ;(TIME - T%)/​100"​s"​
-Here we time how long an empty loop counting to one million takes to execute and store the result in **O%**. This value is used later to offset the time measurements made later. The displayed time is in seconds.\\ \\ +</​code>​ 
 + 
 +Here we time how long an empty loop counting to one million takes to execute and store the result in **O%**. This value is used later to offset the time measurements made later. The displayed time is in seconds. 
 + 
 +<code bb4w>
           REM How long does calling a SYS by name take?           REM How long does calling a SYS by name take?
           T%=TIME+O%           T%=TIME+O%
Line 56: Line 82:
           NEXT           NEXT
           PRINT "SYS by name   : ";​(TIME - T%)/​100"​s"'​           PRINT "SYS by name   : ";​(TIME - T%)/​100"​s"'​
-Here we call "​GetSystemMetrics"​ by name one million times timing how long it takes and display the result in seconds.\\ \\ +</​code>​ 
 + 
 +Here we call "​GetSystemMetrics"​ by name one million times timing how long it takes and display the result in seconds. 
 + 
 +<code bb4w>
           REM How long does calling a SYS by pointer take?           REM How long does calling a SYS by pointer take?
           T%=TIME+O%           T%=TIME+O%
Line 66: Line 96:
           PRINT "SYS by pointer: ";​(TIME - T%)/​100"​s"​           PRINT "SYS by pointer: ";​(TIME - T%)/​100"​s"​
         UNTIL 1=0         UNTIL 1=0
 +</​code>​
 +
 Here we read the function pointer for "​GetSystemMetrics",​ call the function by pointer one million times timing how long it takes and display the result in seconds.\\ \\  If the above code exits with a **Division by zero** error you should increase the value of **C%** by a factor of ten; that is, add an extra zero to **C%**. Here we read the function pointer for "​GetSystemMetrics",​ call the function by pointer one million times timing how long it takes and display the result in seconds.\\ \\  If the above code exits with a **Division by zero** error you should increase the value of **C%** by a factor of ten; that is, add an extra zero to **C%**.
accessing_20the_20fast_20sys_20interface.txt · Last modified: 2018/04/14 20:32 by richardrussell