[Tarantool-patches] [PATCH 15/20] net.box: rewrite request implementation in C

Vladimir Davydov vdavydov at tarantool.org
Thu Aug 5 15:46:24 MSK 2021


On Wed, Aug 04, 2021 at 11:20:04PM +0200, Vladislav Shpilevoy wrote:
> >>> +static int
> >>> +netbox_new_request(struct lua_State *L)
> >>> +{
> >>> +	struct netbox_request *request = lua_newuserdata(L, sizeof(*request));
> >>
> >> 9. Does it help perf if the requests are allocated on mempool?
> > 
> > I tried to allocate requests on mempool. To achieve that, we have to
> > turn them into C data. It resulted in a performance degradation, see the
> > parallel thread:
> 
> It does not necessarily need to be cdata. You can use
> lua_newuserdata(L, sizeof(void *)) and store pointers at the requests which
> you allocate on mempool. The downside is that there will be +1 dereference for
> each access. The upside is that Lua might have optimizations for small userdata
> objects. For example, ffi.new() for objects < 128 bytes is order of magnitude
> faster than for bigger objects. Something similar might exist for userdata.

Tried that - diff is within stdev with the patched version performing
slightly worse:

CALL performance over 5 runs:

                     KRPS(WALL) : KRPS(PROC)
userdata           :  312 +-  7 :  542 +- 20
userdata + mempool :  305 +-  2 :  527 +- 11

Here's the patch I used:
--
diff --git a/src/box/lua/net_box.c b/src/box/lua/net_box.c
index 06e574cdf746..f6dcf1cca920 100644
--- a/src/box/lua/net_box.c
+++ b/src/box/lua/net_box.c
@@ -136,6 +136,8 @@ struct netbox_request {
 	struct error *error;
 };
 
+struct mempool netbox_request_pool;
+
 static const char netbox_registry_typename[] = "net.box.registry";
 static const char netbox_request_typename[] = "net.box.request";
 
@@ -1346,7 +1348,8 @@ luaT_netbox_registry_reset(struct lua_State *L)
 static inline struct netbox_request *
 luaT_check_netbox_request(struct lua_State *L, int idx)
 {
-	return luaL_checkudata(L, idx, netbox_request_typename);
+	return *(struct netbox_request **)luaL_checkudata(
+		L, idx, netbox_request_typename);
 }
 
 static int
@@ -1355,6 +1358,7 @@ luaT_netbox_request_gc(struct lua_State *L)
 	struct netbox_request *request = luaT_check_netbox_request(L, 1);
 	netbox_request_unregister(request);
 	netbox_request_destroy(request);
+	mempool_free(&netbox_request_pool, request);
 	return 0;
 }
 
@@ -1611,8 +1615,10 @@ netbox_make_request(struct lua_State *L, int idx,
 static int
 netbox_perform_async_request(struct lua_State *L)
 {
-	struct netbox_request *request = lua_newuserdata(L, sizeof(*request));
-	netbox_make_request(L, 1, request);
+	struct netbox_request **request_p = lua_newuserdata(
+		L, sizeof(*request_p));
+	*request_p = mempool_alloc(&netbox_request_pool);
+	netbox_make_request(L, 1, *request_p);
 	luaL_getmetatable(L, netbox_request_typename);
 	lua_setmetatable(L, -2);
 	return 1;
@@ -1976,6 +1982,9 @@ netbox_console_loop(struct lua_State *L)
 int
 luaopen_net_box(struct lua_State *L)
 {
+	mempool_create(&netbox_request_pool, cord_slab_cache(),
+		       sizeof(struct netbox_request));
+
 	lua_pushcfunction(L, luaT_netbox_request_iterator_next);
 	luaT_netbox_request_iterator_next_ref = luaL_ref(L, LUA_REGISTRYINDEX);
 


More information about the Tarantool-patches mailing list