lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]



Apply the patch, and compile with -DLUA_NUMBER_MODE=22. You'll get a Lua executable behaving quite normally, but having also full int64 (signed) precision.

API is the same as regular Lua, so extension modules work as such.

-asko


Attachment: int-all-511.patch
Description: Binary data

*
* INT-ALL.PATCH       Copyright (c) 2006 Asko Kauppi, <akauppi@gmail.com>
*

License:    MIT/Lua 5.0
Credits:    ...
Patches:    lapi.c lbaselib.c lcode.[ch] ldebug.c ldo.c ldump.c lobject.[ch]
	        loslib.c lparser.c ltable.c ltm.[ch] lua.h luaconf.h lundump.c
	        lvm.[ch] print.c

History:
    AKa 24-Jul-06: Merged previous 'int-opt.patch' and 'int-vm.patch' together,
            important to get also Lua constants with full integer accuracy.
            Changed NUMBER_MODE values to 1,2, 11,12, 21,22

Int-vm patch history:
    AKa 22-Jul-06: Started... Works early 23st. ;)

Int-opt patch history:
    AKa 4-Aug-06: Needed not fix x/0 case; was already Good. :)))
    AKa 24-Jul-06: Fixed the NUMBER_MODE=65 bug
    AKa 22-Jul-06: Fixed string.format(), now outputs even 64-bit integers.
    Aka 9.2.06: Renamed int32.patch -> intopt.patch
    Aka 5.2.06: Started using LUA_NUMBER_MODE
                Prepared int64 compatibility (someone should test..)

Bugs/to-do:
    - file operations (reading by 'n', and writing) have not been tested

    - general read-through of the patch itself (is it clean, no unnecessary
      white space 'trash' and such..  no debug left-overs)


Purpose:

    The Integer Accuracy patch allows Lua to use 32- or 64-bit integer values
internally for boosting performance on non-FPU platforms, or enabling use
of 64-bit integers without resorting to "long double". It also allows
full 32-bit integer precision to be used, regardless of the 'lua_Number' 
definition (a float can only carry 23 bits of integers, until it starts
losing accuracy).

    Use of this patch on non-float architectures (with FPU, and using
double) is okay, but does not considerably alter runtime performance.
Use of NUMBER_MODE 2 (normal, all numbers double) is recommended on such
platforms, unless there is need for int64 accuracy.

    If NUMBER_MODE's 1 or 2 are used, compiling the code should create code
very close to regular, unpatched Lua (some bug-like fixes aside). This allows
to have the patch in the codebase, ready for people who actually need it,
but not troubling those who can live without.

    Use "make test" (float-test.lua) to check everything is going smoothly
with the numbers.


-----------
    If the Lua authors were to approve this patch, some day, I would
also suggest making the following changes in stock Lua (5.1) code:

  - Add 'lua_isinteger()' to the C API. That function would return 1 for
anything fitting into 'lua_Integer', and not having a fraction part
(regardless if the intopt patch is actually used).

  - Rename 'luaO_str2d()' to 'luaO_str2n' since 'd' refers to 'double' and
is sort of misleading (especially so since printf uses "%d" for integers).
Most likely, the name is but an old remnant? :)

  - Depending on the platform, either 2 (double), 11 (float+int32) or 22 (double+int64)
could be the default.


Sample:

  Lua 5.1  Copyright (C) 1994-2006 Lua.org, PUC-Rio
  > i=1
  > print( type(i) )
  number
  > i=i+0.2
  > print(i)
  1.2
  > 

--------------------------
   Performance results:
--------------------------

AK 24-Jul-06:
NOTE: THESE PERFORMANCE FIGURES WHERE DONE ON OLDER VERSION OF INT-OPT PATCH.
      Use them as guidance only.

To make these performance tests, run:
	make perftest-float
	make perftest-float-int
	make perftest-double
	make perftest-double-int

The sum of "user" and "sys" values matter. The NSLU2 obviously uses "soft float"
(run in user mode) while N770 uses "hard float" (run in sys mode). That's why in 
NSLU2 numbers, the sys parts are rather irrelevant.

The tests are run multiple times, to see out statistical noise of the results.

Performance test must always be done with "-O2" optimization (NOT debug info,
or asserts!) and stripped binaries.

The binaries are without readline, or other such extras.


** iMac PowerPC G4 700MHz/512 MB, OS X 10.4.4 **

Sat Jan 21 00:51:29 EET 2006 / Asko Kauppi

Note: These measurements are 'user' values only, should be: 'user'+'sys'
      since both affect.  Sorry. :)

float: 		1.07 1.10 1.10 1.09 (1.0900 = 100%)	143 792 bytes
float+int32:	1.11 1.08 1.08 1.08 (1.0875 =  99.8%)	147 920 bytes (+4128)
float+int64:*	1.177+0.037 =1.214  1.167+0.031 =1.198 1.177+0.032= 1.209 (1.207 = 110.7%)
double:		1.14 1.12 1.11 1.11 (1.1200 = 102.8%)	143 780 bytes (-12)
double+int32:	1.14 1.11 1.11 1.11 (1.1175 = 102.5%)	147 908 bytes (+4116)
double+int64:*	1.18+0.036 =1.216 1.176+0.029 =1.205 1.173+0.029 =1.202  (1.208 = 110.8%)

*) measured with 5.1rc4, therefore not completely comparable with the other figures.


** NSLU2 ARM 266MHz/32 MB, Linux unslung 2.4.22 **

Sat Jan 21 02:34:22 EET 2006 / Asko Kauppi

NSLU2 'time' gives three decimals, but the lowest is always zero
(and was left out of the statistics here)

float: 		5.06+0.14 =5.20  5.11+0.09 =5.20  (5.200 = 100%)     126 472 bytes
float+int:	3.39+0.07 =3.46  3.34+0.12 =3.46  (3.460 =  66.5%)   130 020 bytes (+3548)
double:		5.85+0.09 =5.94  5.88+0.06 =5.94  (5.940 = 114.2%)   127 224 bytes (+752)
double+int: 	3.58+0.09 =3.67  3.61+0.06 =3.67  (3.670 =  70.6%)   130 724 bytes (+4252)

Running test/life.lua and measuring time (with a watch) of 200 cycles:
(note: do this by first "make perftest-xx" to have the binaries optimized,
and without debug & assert information)

float:		39.60 sec  (100%)
float+int:	 7.08 sec  ( 17.9%)
double:		44.00 sec  (111.1%)
double+int:	 7.32 sec  ( 18.5%)


** N770 ARM 200MHz/64 MB, w45/2005 rootstrap **

Mon Jan 23 02:01:54 EET 2006 / Asko Kauppi

With the N770, system part of timings is noticeable for non-integer variants.
Interestingly, double+int is faster than float+int.

'time lua speed-test.lua 1000' (user+sys):
float: 		5.53+3.16 =8.69  5.54+3.10 =8.64  (8.665 = 100%)    126 740 bytes
float+int:	5.53+0.28 =5.81  6.35+0.27 =6.62  (6.215 =  76.6%)  129 864 bytes (+3120)
double:		5.19+4.05 =9.24  5.03+4.09 =9.12  (9.180 = 105.9%)  127 492 bytes (+752)
double+int:	5.43+0.26 =5.69  5.41+0.31 =5.72  (5.705 =  65.8%)  130 584 bytes (+3844)

'time lua speed-test.lua 10000':
float: 		real 86.74 user 53.60 sys 33.01 -> user+sys 86.61 (100%)
float+int:	real 65.61 user 62.31 sys 02.68 -> user+sys 64.99 ( 75.0%)
double:		real 92.70 user 51.39 sys 40.23 -> user+sys 91.62 (105.8%)
double+int: 	real 57.64 user 54.67 sys 02.67 -> user+sys 57.34 ( 66.2%)


Running test/life.lua, in terminal fullscreen mode.
200 cycles (50, or 100 cycles measured & extrapolated):

float:		85.64 sec  (100%)
float+int:	28.48 sec  ( 33.3%)
double:		92.12 sec  (107.6%)
double+int:	28.64 sec  ( 33.4%)


** Your Device? :) **

..more actual hw test results to be placed here..


-end-


Matt Campbell kirjoitti 24.8.2006 kello 3.47:

Hello Jason:

Because Lua's only numeric data type is a floating point number (a C
double), Lua doesn't support arbitrary 64-bit integers (long longs).
However, according to the book Programming in Lua, it does support
integers up to 100,000,000,000,000. So your best bet is just to push the
long long using lua_pushnumber and let the compiler convert it to a
double. Does anyone else have additional information on this?

--
Matt Campbell
Lead Programmer
Serotek Corporation
www.freedombox.info
"The Accessibility Anywhere People"