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

Next revision
Previous revision
accessing_20the_20fast_20sys_20interface [2018/03/31 13:19] – external edit 127.0.0.1accessing_20the_20fast_20sys_20interface [2024/01/05 00:22] (current) – external edit 127.0.0.1
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.1522502343.txt.gz · Last modified: 2024/01/05 00:18 (external edit)