8000 perf: update 1mops to support memcs by mkostoevr · Pull Request #11293 · tarantool/tarantool · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

perf: update 1mops to support memcs #11293

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 47 additions & 20 deletions perf/lua/1mops_write.lua
10000
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ local fiber = require('fiber')
local math = require('math')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo in commit " perf: update the 1mops_write test to support memcs": s/pref/perf/

local json = require('json')
local fio = require('fio')
local tarantool = require('tarantool')

-- XXX: This benchmark should be able to work standalone without
-- any provided libraries or set LUA_PATH. Add stubs for that
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo in commit "perf: update the 1mops_write test to support memcs": s/pref/perf/

Expand Down Expand Up @@ -43,6 +44,7 @@ local HELP = [[
local parsed_params = {
{'engine', 'string'},
{'fibers', 'number'},
{'columns', 'number'},
{'index', 'string'},
{'nodes', 'number'},
{'nohint', 'boolean'},
Expand All @@ -53,6 +55,12 @@ local parsed_params = {
{'warmup', 'number'},
}

local BUILDDIR = fio.abspath(fio.pathjoin(os.getenv('BUILDDIR') or '.'))
local MODULEPATH = fio.pathjoin(BUILDDIR, 'perf', 'lua',
'?.' .. tarantool.build.mod_format)
package.cpath = MODULEPATH .. ';' .. package.cpath
local module_is_available, module = pcall(require, '1mops_write_module')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/module_is_available/1mops_write_module/
s/module/1mops_write_module/

and probably it is better to rename 1mops_write_module to something that will reflect specific of this module. may be column_write_module?


local params
local bench

Expand Down Expand Up @@ -117,14 +125,18 @@ local nodes = params.nodes or 1

-- engine to use
local engine = params.engine or 'memtx'
assert(engine == 'memtx' or engine == 'vinyl')
assert(engine == 'memtx' or engine == 'vinyl' or engine == 'memcs')

-- WAL mode
local wal_mode = params.wal_mode or 'write'
assert(wal_mode == 'write'
or wal_mode == 'none'
or wal_mode == 'fsync')

-- number of columns in the table
local num_columns = params.columns or 1
assert(num_columns >= 1)

-- type of index to use
local index_config = {}
index_config.type = params.index or 'HASH'
Expand Down Expand Up @@ -157,14 +169,14 @@ local std_redirect = {
}

print(string.format([[
# making %d REPLACE operations,
# making %d REPLACE operations in %s engine,
# %d operations per txn,
# using %d fibers,
# in a replicaset of %d nodes,
# using %s index type%s
# with WAL mode %s
# ]],
num_ops, ops_per_txn, num_fibers, nodes,
num_ops, engine, ops_per_txn, num_fibers, nodes,
index_config.type, hints_msg, wal_mode))

box.cfg{
Expand Down Expand Up @@ -223,21 +235,25 @@ if (nodes > 1) then
end
end

local space
local done = false
local err

if (test_sync) then
box.cfg{replication_synchro_quorum = nodes}
print('# promoting')
box.ctl.promote()
print('# done')
space, err = box.schema.create_space('test',
{engine = engine, is_sync = true})
else
space, err = box.schema.create_space('test',
{engine = engine})
end

local done = false
local space_format = {}
for i = 1, num_columns do
table.insert(space_format, {'field_' .. tostring(i), 'unsigned'})
end
local create_space_opts = {
engine = engine,
field_count = num_columns,
format = space_format,
is_sync = test_sync or nil
}
local space, err = box.schema.create_space('test', create_space_opts)
if space == false then
exit(1, 'error creating space ' .. json.encode(err))
end
Expand All @@ -247,17 +263,28 @@ if (res ~= true) then
json.encode(index_config) .. ' :' .. json.encode(err))
end

-- Preallocate the test tuple
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previous comments started from lowercase letter

local tuple = {}
for i = 1, num_columns do -- luacheck: no unused
table.insert(tuple, 0)
end

-- THE load fiber
local function fiber_load(start, s)
start = start % 1000000 -- limit the size of space to 1M elements
for _ = 1, trans_per_fiber do
box.begin()
for _ = 1, ops_per_txn do
s:replace{start}
start = start + 1
if module_is_available then
module.fiber(s.id, trans_per_fiber, ops_per_txn, num_columns, start)
else
for _ = 1, trans_per_fiber do
box.begin()
for _ = 1, ops_per_txn do
tuple[1] = start
s:replace(tuple)
start = start + 1
end
box.commit()
fiber.yield()
end
box.commit()
fiber.yield()
end
end

Expand Down Expand Up @@ -307,7 +334,7 @@ end)

-- start fibers for the main load
for i = 1, num_fibers do
fibers_storage[i] = fiber.create(fiber_load, i*num_ops, space)
fibers_storage[i] = fiber.create(fiber_load, i*(num_ops/num_fibers), space)
if (fibers_storage[i]:status() ~= 'dead') then
fibers_storage[i]:wakeup() -- needed for backward compatibility with 1.7
end
Expand Down
173 changes: 173 additions & 0 deletions perf/lua/1mops_write_module.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
#include <lua.h>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit confused how many low-level memcs modules we already have:

perf/lua/1mops_write_module.c
perf/lua/column_insert_module.c
perf/lua/column_scan_module.c

Do you ever plan to introduce a Lua API to memcs?

#include <lauxlib.h>
#include <module.h>
#include <msgpuck.h>
#include <stddef.h>
#include <stdint.h>

#include "trivia/config.h"
#include "trivia/util.h"

/** Template tuples to update and insert: one per PK msgpack field size. */
static char *base_tuple_pk1;
static char *base_tuple_pk1_end;
static char *base_tuple_pk2;
static char *base_tuple_pk2_end;
static char *base_tuple_pk3;
static char *base_tuple_pk3_end;
static char *base_tuple_pk5;
static char *base_tuple_pk5_end;

static bool
find_base_tuple(uint32_t pk_value, char **tuple, char **tuple_end)
{
size_t sizeof_pk_value = mp_sizeof_uint(pk_value);
switch (sizeof_pk_value) {
case 1:
*tuple = base_tuple_pk1;
*tuple_end = base_tuple_pk1_end;
return true;
case 2:
*tuple = base_tuple_pk2;
*tuple_end = base_tuple_pk2_end;
return true;
case 3:
*tuple = base_tuple_pk3;
*tuple_end = base_tuple_pk3_end;
return true;
case 5:
*tuple = base_tuple_pk5;
*tuple_end = base_tuple_pk5_end;
return true;
}
box_error_raise(ER_UNSUPPORTED, "No tuple for PK value of size %lu, "
"value: %u", sizeof_pk_value, pk_value);
return false;
}

static bool
test_tuple(uint32_t pk_value, char **tuple, char **tuple_end)
{
/* Get the tuple to update. */
if (!find_base_tuple(pk_value, tuple, tuple_end))
return false;

/* Check if the new PK value is of exact size. */
const char *data = *tuple;
mp_decode_array(&data);
char *pk_value_ptr = (char *)data;
uint32_t old_pk_value = mp_decode_uint(&data);
if (mp_sizeof_uint(pk_value) != mp_sizeof_uint(old_pk_value)) {
box_error_raise(ER_UNSUPPORTED, "Wrong base tuple, "
"PK value %u", pk_value);
return false;
}

/* Write the new PK value. */
mp_encode_uint(pk_value_ptr, pk_value);
return true;
}

static char *
encode_base_tuple(char *data, ptrdiff_t *data_sz,
uint32_t pk_value, uint32_t num_columns)
{
data = mp_encode_array_safe(data, data_sz, num_columns);
data = mp_encode_uint_safe(data, data_sz, pk_value);
for (uint32_t i = 1; i < num_columns; i++)
data = mp_encode_uint_safe(data, data_sz, 0);
return data;
}

static bool
create_base_tuples(uint32_t num_columns)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused that we test engine by a limit number of datatypes. Should we parametrize a test (or probably add another one) that will test memcs by different datatypes (standard msgpack types and our extensions 1).

Footnotes

  1. https://www.tarantool.io/en/doc/latest/reference/internals/msgpack_extensions/

{
uint32_t uint_1 = 0;
uint32_t uint_2 = UINT8_MAX;
uint32_t uint_3 = UINT16_MAX;
uint32_t uint_5 = UINT32_MAX;
if (mp_sizeof_uint(uint_1) != 1 ||
mp_sizeof_uint(uint_2) != 2 ||
mp_sizeof_uint(uint_3) != 3 ||
mp_sizeof_uint(uint_5) != 5) {
box_error_raise(ER_UNKNOWN, "PK value size assertion failed");
return false;
}

struct {
uint32_t pk_value;
char **ptr;
char **end;
} base_tuples[] = {
{ uint_1, &base_tuple_pk1, &base_tuple_pk1_end },
{ uint_2, &base_tuple_pk2, &base_tuple_pk2_end },
{ uint_3, &base_tuple_pk3, &base_tuple_pk3_end },
{ uint_5, &base_tuple_pk5, &base_tuple_pk5_end },
};

for (size_t i = 0; i < lengthof(base_tuples); i++) {
uint32_t pk_value = base_tuples[i].pk_value;
char **base_tuple_ptr = base_tuples[i].ptr;
char **base_tuple_end_ptr = base_tuples[i].end;

ptrdiff_t sizeof_tuple = 0;
encode_base_tuple(NULL, &sizeof_tuple, pk_value, num_columns);
*base_tuple_ptr = xcalloc((uint32_t)sizeof_tuple, 1);
*base_tuple_end_ptr = encode_base_tuple(*base_tuple_ptr, NULL,
pk_value, num_columns);
}
return true;
}

static bool
do_transaction(uint32_t space_id, uint32_t ops_per_txn, uint32_t *start)
{
if (box_txn_begin() != 0)
return false;
for (uint32_t j = 0; j < ops_per_txn; j++) {
char *tuple, *tuple_end;
if (!test_tuple(*start, &tuple, &tuple_end))
goto fail;
box_tuple_t *result;
if (box_replace(space_id, tuple,
tuple_end, &result) != 0)
goto fail;
++*start;
}
return box_txn_commit() == 0;

fail:
box_txn_commit();
return false;
}

static int
fiber_lua_func(struct lua_State *L)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems function has nothing common with fibers, I would rename it.

{
uint32_t space_id = luaL_checkinteger(L, 1);
uint32_t trans_per_fiber = luaL_checkinteger(L, 2);
uint32_t ops_per_txn = luaL_checkinteger(L, 3);
uint32_t num_columns = luaL_checkinteger(L, 4);
uint32_t start = luaL_checkinteger(L, 5);
if (!create_base_tuples(num_columns))
return luaT_error(L);
bool success = true;
for (uint32_t i = 0; success && i < trans_per_fiber; i++) {
success = do_transaction(space_id, ops_per_txn, &start);
fiber_sleep(0);
}
if (!success)
return luaT_error(L);
return 0;
}

LUA_API int
luaopen_1mops_write_module(struct lua_State *L)
Copy link
EEE9
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know how to ensure that 1mops_write_module.c uses memcs API in the same way as TCS. Should we involve someone from TCS team to review?

{
static const struct luaL_Reg lib[] = {
{"fiber", fiber_lua_func},
{NULL, NULL},
};
luaL_register(L, "1mops_write_module", lib);
return 1;
}
7 changes: 6 additions & 1 deletion perf/lua/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ function(create_perf_lua_test)
DEPENDS ${BENCH_TARGET}-deps)
endfunction()

create_perf_lua_test(NAME 1mops_write)
create_perf_lua_test(NAME box_select)
create_perf_lua_test(NAME gh-7089-vclock-copy)
create_perf_lua_test(NAME luafun)
Expand All @@ -73,6 +72,12 @@ create_perf_lua_test(NAME uri_escape_unescape)

include_directories(${MSGPUCK_INCLUDE_DIRS})

build_module(1mops_write_module 1mops_write_module.c)
target_link_libraries(1mops_write_module msgpuck)
create_perf_lua_test(NAME 1mops_write
DEPENDS column_scan_module
)

build_module(column_scan_module column_scan_module.c)
target_link_libraries(column_scan_module msgpuck)
create_perf_lua_test(NAME column_scan
Expand Down
Loading
0