ravi array revision

pull/81/head
Dibyendu Majumdar 9 years ago
parent d777bec358
commit 5ea7c3bd28

@ -43,47 +43,69 @@ LUAI_FUNC void luaH_free (lua_State *L, Table *t);
LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key);
LUAI_FUNC int luaH_getn (Table *t);
LUAI_FUNC Table *raviH_new(lua_State *L, ravitype_t tt); /* RAVI array specialization */
LUAI_FUNC int raviH_getn(Table *t); /* RAVI array specialization */
LUAI_FUNC void raviH_set_int(lua_State *L, Table *t, unsigned int key, lua_Integer value); /* RAVI array specialization */
LUAI_FUNC void raviH_set_float(lua_State *L, Table *t, unsigned int key, lua_Number value); /* RAVI array specialization */
#define raviH_get_int_inline(L, t, key, v) \
{ unsigned int ukey = (unsigned int)((key)); \
lua_Integer *data = (lua_Integer *)t->ravi_array.data; \
if (ukey < t->ravi_array.len) {\
setivalue(v, data[ukey]); \
} else \
luaG_runerror(L, "array out of bounds"); \
/* RAVI array specialization */
/* Creates a specialized version of Lua Table to support Ravi's
* integer[] and number[] arrays.
*/
LUAI_FUNC Table *raviH_new(lua_State *L, ravitype_t array_type);
/* Returns the array length - note that this function will
* ignore any elements outside of the Ravi Array structure
*/
LUAI_FUNC int raviH_getn(Table *t);
/* Type specific array set operation */
LUAI_FUNC void raviH_set_int(lua_State *L, Table *t, unsigned int key,
lua_Integer value);
/* Type specific array set operation */
LUAI_FUNC void raviH_set_float(lua_State *L, Table *t, unsigned int key,
lua_Number value);
/* Type specific array get operation */
#define raviH_get_int_inline(L, t, key, v) \
{ \
unsigned int ukey = (unsigned int)((key)); \
lua_Integer *data = (lua_Integer *)t->ravi_array.data; \
if (ukey < t->ravi_array.len) { \
setivalue(v, data[ukey]); \
} else \
luaG_runerror(L, "array out of bounds"); \
}
#define raviH_get_float_inline(L, t, key, v) \
{ unsigned int ukey = (unsigned int)((key)); \
lua_Number *data = (lua_Number *)t->ravi_array.data; \
if (ukey < t->ravi_array.len) {\
setfltvalue(v, data[ukey]); \
}else \
luaG_runerror(L, "array out of bounds"); \
/* Type specific array get operation */
#define raviH_get_float_inline(L, t, key, v) \
{ \
unsigned int ukey = (unsigned int)((key)); \
lua_Number *data = (lua_Number *)t->ravi_array.data; \
if (ukey < t->ravi_array.len) { \
setfltvalue(v, data[ukey]); \
} else \
luaG_runerror(L, "array out of bounds"); \
}
#define raviH_set_int_inline(L, t, key, value) \
{ unsigned int ukey = (unsigned int)((key)); \
lua_Integer *data = (lua_Integer *)t->ravi_array.data; \
if (ukey < t->ravi_array.len) { \
data[ukey] = value; \
} else \
raviH_set_int(L, t, ukey, value); \
/* Type specific array set operation */
#define raviH_set_int_inline(L, t, key, value) \
{ \
unsigned int ukey = (unsigned int)((key)); \
lua_Integer *data = (lua_Integer *)t->ravi_array.data; \
if (ukey < t->ravi_array.len) { \
data[ukey] = (value); \
} else \
raviH_set_int(L, t, ukey, (value)); \
}
#define raviH_set_float_inline(L, t, key, value) \
{ unsigned int ukey = (unsigned int)((key)); \
lua_Number *data = (lua_Number *)t->ravi_array.data; \
if (ukey < t->ravi_array.len) { \
data[ukey] = value; \
} else \
raviH_set_float(L, t, ukey, value); \
}
/* Type specific array set operation */
#define raviH_set_float_inline(L, t, key, value) \
{ \
unsigned int ukey = (unsigned int)((key)); \
lua_Number *data = (lua_Number *)t->ravi_array.data; \
if (ukey < t->ravi_array.len) { \
data[ukey] = (value); \
} else \
raviH_set_float(L, t, ukey, (value)); \
}
#if defined(LUA_DEBUG)
LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key);

@ -729,7 +729,7 @@
*/
#if _WIN32
#if _WIN32 && _MSC_VER < 1900
#define snprintf _snprintf
#endif

@ -10,13 +10,13 @@ The programs used in the performance testing can be found at `Ravi Tests <https:
+===============+=========+==========+===========+
|fornum_test1 | 9.187 | 2.75 | 0.309 |
+---------------+---------+----------+-----------+
|fornum_test2 | 9.57 | 1.234 | 0.93 |
|fornum_test2 | 9.57 | 0.922 | 0.906 |
+---------------+---------+----------+-----------+
|fornum_test3 | 53.932 | 7.062 | 7.806 |
|fornum_test3 | 53.932 | 4.593 | 7.778 |
+---------------+---------+----------+-----------+
|mandel(4000) | 21.247 | 2.953 | 1.633 |
|mandel(4000) | 21.247 | 2.94 | 1.633 |
+---------------+---------+----------+-----------+
|fannkuchen(11) | 63.446 | 9.017 | 4.751 |
|fannkuchen(11) | 63.446 | 8.875 | 4.751 |
+---------------+---------+----------+-----------+
There are a number of reasons why Ravi's performance is not as good as Luajit.

@ -75,8 +75,10 @@ I am currently working on JIT compilation of Ravi using LLVM. As of now all byte
There are two modes of JIT compilation.
* auto mode - in this mode the compiler decides when to compile a Lua function. The current implementation is very simple - any Lua function call is checked to see if the bytecodes contained in it can be compiled. If this is true then the function is compiled provided a) function has a fornum loop, b) it is largish (greater than 150 bytecodes) or c) it is being executed many times (> 50). Because of the simplistic behaviour performance the benefit of JIT compilation is only available if the JIT compiled functions will be executed many times so that the cost of JIT compilation can be amortized.
* manual mode - in this mode user must explicitly request compilation. This is the default mode. This mode is suitable for library developers who can pre compile the functions in library module table.
auto mode
in this mode the compiler decides when to compile a Lua function. The current implementation is very simple - any Lua function call is checked to see if the bytecodes contained in it can be compiled. If this is true then the function is compiled provided a) function has a fornum loop, b) it is largish (greater than 150 bytecodes) or c) it is being executed many times (> 50). Because of the simplistic behaviour performance the benefit of JIT compilation is only available if the JIT compiled functions will be executed many times so that the cost of JIT compilation can be amortized.
manual mode
in this mode user must explicitly request compilation. This is the default mode. This mode is suitable for library developers who can pre compile the functions in library module table.
A JIT api is available with following functions:
@ -184,9 +186,12 @@ The Ravi build creates a shared library, the Lua executable and some test progra
The ``lua`` command recognizes following environment variables. Note that these are only for internal debugging purposes.
* ``RAVI_DEBUG_EXPR`` - if set to a value this triggers debug output of expression parsing
* ``RAVI_DEBUG_CODEGEN`` - if set to a value this triggers a dump of the code being generated
* ``RAVI_DEBUG_VARS`` - if set this triggers a dump of local variables construction and destruction
``RAVI_DEBUG_EXPR``
if set to a value this triggers debug output of expression parsing
``RAVI_DEBUG_CODEGEN``
if set to a value this triggers a dump of the code being generated
``RAVI_DEBUG_VARS``
if set this triggers a dump of local variables construction and destruction
Also see section above on available API for dumping either Lua bytecode or LLVM IR for compiled code.

@ -664,7 +664,8 @@ int luaH_getn (Table *t) {
unsigned int j;
/* if this is a RAVI array then use specialized function */
if (t->ravi_array.array_type != RAVI_TTABLE) {
lua_assert(t->ravi_array.array_type == RAVI_TARRAYFLT || t->ravi_array.array_type == RAVI_TARRAYINT);
lua_assert(t->ravi_array.array_type == RAVI_TARRAYFLT ||
t->ravi_array.array_type == RAVI_TARRAYINT);
return t->ravi_array.len;
}
j = t->sizearray;
@ -687,14 +688,15 @@ int luaH_getn (Table *t) {
/* RAVI array specialization */
int raviH_getn(Table *t) {
lua_assert(t->ravi_array.array_type != RAVI_TTABLE);
return t->ravi_array.len-1;
return t->ravi_array.len - 1;
}
static void ravi_resize_array(lua_State *L, Table *t) {
unsigned int size = t->ravi_array.size + 10;
t->ravi_array.data = (char *) luaM_reallocv(L, t->ravi_array.data, t->ravi_array.size, size, sizeof(lua_Number));
lua_Number *data = (lua_Number*) t->ravi_array.data;
memset(&data[t->ravi_array.len], 0, size-t->ravi_array.size);
t->ravi_array.data = (char *)luaM_reallocv(
L, t->ravi_array.data, t->ravi_array.size, size, sizeof(lua_Number));
lua_Number *data = (lua_Number *)t->ravi_array.data;
memset(&data[t->ravi_array.len], 0, size - t->ravi_array.size);
t->ravi_array.size = size;
}
@ -705,19 +707,16 @@ void raviH_set_int(lua_State *L, Table *t, unsigned int u, lua_Integer value) {
setval2:
data = (lua_Integer *)t->ravi_array.data;
data[u] = value;
}
else if (u == t->ravi_array.len) {
} else if (u == t->ravi_array.len) {
if (u < t->ravi_array.size) {
setval:
t->ravi_array.len++;
goto setval2;
}
else {
} else {
ravi_resize_array(L, t);
goto setval;
}
}
else
} else
luaG_runerror(L, "array out of bounds");
}
@ -728,19 +727,16 @@ void raviH_set_float(lua_State *L, Table *t, unsigned int u, lua_Number value) {
setval2:
data = (lua_Number *)t->ravi_array.data;
data[u] = value;
}
else if (u == t->ravi_array.len) {
} else if (u == t->ravi_array.len) {
if (u < t->ravi_array.size) {
setval:
t->ravi_array.len++;
goto setval2;
}
else {
} else {
ravi_resize_array(L, t);
goto setval;
}
}
else
} else
luaG_runerror(L, "array out of bounds");
}
@ -750,14 +746,12 @@ Table *raviH_new(lua_State *L, ravitype_t tt) {
t->ravi_array.array_type = tt;
if (tt == RAVI_TARRAYFLT) {
raviH_set_float_inline(L, t, 0, 0.0);
}
else {
} else {
raviH_set_int_inline(L, t, 0, 0);
}
return t;
}
#if defined(LUA_DEBUG)
Node *luaH_mainposition (const Table *t, const TValue *key) {

@ -1180,7 +1180,7 @@ newframe: /* reentry point when frame changes (call/return) */
int i = last-n+1;
for (; i <= (int)last; i++) {
TValue *val = ra + i;
lua_Unsigned u = (lua_Unsigned)(i);
unsigned int u = (unsigned int)(i);
switch (h->ravi_array.array_type) {
case RAVI_TARRAYINT: {
if (ttisinteger(val))
@ -1640,7 +1640,7 @@ void raviV_op_setlist(lua_State *L, CallInfo *ci, TValue *ra, int b, int c) {
int i = last - n + 1;
for (; i <= (int)last; i++) {
TValue *val = ra + i;
lua_Unsigned u = (lua_Unsigned)(i);
unsigned int u = (unsigned int)(i);
switch (h->ravi_array.array_type) {
case RAVI_TARRAYINT: {
if (ttisinteger(val))

Loading…
Cancel
Save