From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from [87.239.111.99] (localhost [127.0.0.1]) by dev.tarantool.org (Postfix) with ESMTP id CFE11718B1; Tue, 19 Jan 2021 02:51:10 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org CFE11718B1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1611013870; bh=kp8IdnULHJaB21vaaK07PYj7e1fhdWtbndkU6clgp9I=; h=To:Date:In-Reply-To:References:In-Reply-To:References:Subject: List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help: List-Subscribe:From:Reply-To:Cc:From; b=n4dM5lTELrsTbMR7TfQU6ubfHDOshPPx8jdoRycBa5W+GNR6V6MdS6Dsl+wXqO8pT yWxxeL9uckzLrJtjHdjuVXaaBZirmXjIyCXttMs2U1j0HRJfkPWXdX7ltMFB8wr7je br+oPMkJzoehvoQv0tatokFYx24aZZJoKxg19TXE= Received: from smtp43.i.mail.ru (smtp43.i.mail.ru [94.100.177.103]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id 270F2718B1 for ; Tue, 19 Jan 2021 02:50:40 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 270F2718B1 Received: by smtp43.i.mail.ru with esmtpa (envelope-from ) id 1l1eIB-000553-3o; Tue, 19 Jan 2021 02:50:39 +0300 To: v.shpilevoy@tarantool.org, alyapunov@tarantool.org Date: Tue, 19 Jan 2021 02:50:30 +0300 Message-Id: X-Mailer: git-send-email 2.17.1 In-Reply-To: References: In-Reply-To: References: X-7564579A: 646B95376F6C166E X-77F55803: 4F1203BC0FB41BD9D0E79FBC973162CD520EA9A9E182CF906B1BCD0E5756442500894C459B0CD1B92E4F9ADC44795D9BBA72CC0B387E025A5BDEB18AB7251EEF9AC4FB3CC3F48C31 X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE7D96557C5EC1D5BA4EA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F7900637A9F4748B3793778A8638F802B75D45FF5571747095F342E8C7A0BC55FA0FE5FC76BE4C15C5329EC4A2329A67CD96B17BB2D501201AFFCACC389733CBF5DBD5E913377AFFFEAFD269176DF2183F8FC7C0D9442B0B5983000E8941B15DA834481FCF19DD082D7633A0EF3E4896CB9E6436389733CBF5DBD5E9D5E8D9A59859A8B652D31B9D28593E51CC7F00164DA146DA6F5DAA56C3B73B237318B6A418E8EAB8D32BA5DBAC0009BE9E8FC8737B5C2249C94F115956DE4A7A76E601842F6C81A12EF20D2F80756B5F7E9C4E3C761E06A776E601842F6C81A127C277FBC8AE2E8B374CE26A9E38610E3AA81AA40904B5D9DBF02ECDB25306B2B25CBF701D1BE8734AD6D5ED66289B5278DA827A17800CE797E1AC076310AD6267F23339F89546C5A8DF7F3B2552694A6FED454B719173D6725E5C173C3A84C3FD340EA919DED65B35872C767BF85DA2F004C906525384306FED454B719173D6462275124DF8B9C9DF33B08B2BB81206574AF45C6390F7469DAA53EE0834AAEE X-C1DE0DAB: C20DE7B7AB408E4181F030C43753B8186998911F362727C4C7A0BC55FA0FE5FC76BE4C15C5329EC4A2329A67CD96B17BCAA2648D4294E94DB1881A6453793CE9C32612AADDFBE061C61BE10805914D3804EBA3D8E7E5B87ABF8C51168CD8EBDBC908CD1B87A134A2DC48ACC2A39D04F89CDFB48F4795C241BDAD6C7F3747799A X-C8649E89: 4E36BF7865823D7055A7F0CF078B5EC49A30900B95165D34682FD2D2951524C573904C57E880B1E4EF95BF720534FD89DBE02AF39FE0E8B6EBC6A3794AC437FC1D7E09C32AA3244C2BB7AE3346181E54BD04F90EE0CF6C4CC3B3ADDA61883BB5927AC6DF5659F194 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojbL9S8ysBdXjuG74y4HcDPWjdGP8sOb6h X-Mailru-Sender: 06752BE58DD8CE37E6C4CE7F78F2F1FBE274B1144DA1F641389DAE4273F6DD7338066306E4938E9F40CFBDB3DDA0AC31AAFFD2005305549D2F0B9811F39295BF38C65A79EEA694937402F9BA4338D657ED14614B50AE0675 X-Mras: Ok Subject: [Tarantool-patches] [PATCH 1/4] tuple: introduce unit perf test based on gbench X-BeenThere: tarantool-patches@dev.tarantool.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Ilya Kosarev via Tarantool-patches Reply-To: Ilya Kosarev Cc: tarantool-patches@dev.tarantool.org Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" To verify that tuple actions performance is fine after notable struct tuple reassembling the perf test is introduced. It tests creation, deletion, field & data access actions for tuple. By default, unit perf tests based on gbench are being assembled in case the google benchmark submodule is being found. Otherwise they are being silently ignored. If needed, unit perf tests assembling can be enforced or disabled using -DWITH_UNIT_PERF_TESTS=ON or -DWITH_UNIT_PERF_TESTS=OFF. Part of #5385 --- .gitignore | 2 + CMakeLists.txt | 1 + perf/CMakeLists.txt | 34 ++++++++ perf/tuple.cc | 185 ++++++++++++++++++++++++++++++++++++++++++++ src/box/alter.cc | 2 +- 5 files changed, 223 insertions(+), 1 deletion(-) create mode 100644 perf/CMakeLists.txt create mode 100644 perf/tuple.cc diff --git a/.gitignore b/.gitignore index 70784d2b3..4a6ec0e2d 100644 --- a/.gitignore +++ b/.gitignore @@ -42,6 +42,7 @@ doc/*/Makefile extra/Makefile extra/*/Makefile extra/luarocks/hardcoded.lua +perf/Makefile test/Makefile test/*/Makefile Doxyfile.API @@ -88,6 +89,7 @@ src/box/lua/*.lua.c src/tarantool src/module.h tarantool-*.tar.gz +perf/*.perftest test/lib/ test/unit/*.test test/unit/fiob diff --git a/CMakeLists.txt b/CMakeLists.txt index 4fbd19558..17b0aee00 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -550,6 +550,7 @@ include (cmake/rpm.cmake) add_subdirectory(src) add_subdirectory(extra) add_subdirectory(test) +add_subdirectory(perf) add_subdirectory(doc) option(WITH_NOTIFY_SOCKET "Enable notifications on NOTIFY_SOCKET" ON) diff --git a/perf/CMakeLists.txt b/perf/CMakeLists.txt new file mode 100644 index 000000000..5b7038e05 --- /dev/null +++ b/perf/CMakeLists.txt @@ -0,0 +1,34 @@ +set(CMAKE_CXX_STANDARD 11) + +set(PERF_TESTS_OPTION ON) + +if (NOT DEFINED WITH_UNIT_PERF_TESTS) + set(PERF_TESTS_OPTION OFF) +endif() + +if (PERF_TESTS_OPTION AND NOT WITH_UNIT_PERF_TESTS) + return() +endif() + +find_package(benchmark QUIET) +if (NOT ${benchmark_FOUND}) + if (PERF_TESTS_OPTION AND WITH_UNIT_PERF_TESTS) + message(FATAL_ERROR "Google Benchmark submodule not found") + else() + message(AUTHOR_WARNING "Google Benchmark submodule not found") + endif() + return() +endif() + +file(GLOB all_sources *.c *.cc) + +if(NOT TARGET_OS_OPENBSD) + set(LIB_DL "dl") +endif() + +include_directories(${MSGPUCK_INCLUDE_DIRS}) +include_directories(${PROJECT_SOURCE_DIR}/src/box) +include_directories(${CMAKE_SOURCE_DIR}/third_party) + +add_executable(tuple.perftest tuple.cc) +target_link_libraries(tuple.perftest core box tuple benchmark::benchmark) diff --git a/perf/tuple.cc b/perf/tuple.cc new file mode 100644 index 000000000..4d50a49b6 --- /dev/null +++ b/perf/tuple.cc @@ -0,0 +1,185 @@ +#include "memory.h" +#include "fiber.h" +#include "tuple.h" + +#include + +#include + +const size_t amount = 1000, index_count = 4; +char **start; +char **end; +std::vector tuples; +std::vector big_tuples; +std::vector tiny_tuples; + +static void +create_tuple(benchmark::State& state) +{ + size_t i = 0; + for (auto _ : state) { + struct tuple *tuple = tuple_new(box_tuple_format_default(), + start[i % amount], + end[i % amount]); + tuple_ref(tuple); + tuple_unref(tuple); + i++; + } +} +BENCHMARK(create_tuple); + +static inline int +access_fields(struct tuple *tuple) +{ + int sum = 0; + sum += tuple->refs; + sum += tuple->format_id; + sum += tuple->bsize; + sum += tuple->data_offset; + sum += tuple->is_dirty; + return sum; +} + +static void +access_tuple_fields(benchmark::State& state) +{ + size_t i = 0; + int64_t sum = 0; + for (auto _ : state) { + struct tuple *tuple = tuples[i++ % tuples.size()]; + sum += access_fields(tuple); + } + assert(sum > 0); +} +BENCHMARK(access_tuple_fields); + +static void +access_tiny_tuple_fields(benchmark::State& state) +{ + size_t i = 0; + int64_t sum = 0; + for (auto _ : state) { + struct tuple *tuple = tiny_tuples[i++ % tiny_tuples.size()]; + sum += access_fields(tuple); + } + assert(sum > 0); +} +BENCHMARK(access_tiny_tuple_fields); + +static void +access_big_tuple_fields(benchmark::State& state) +{ + size_t i = 0; + int64_t sum = 0; + for (auto _ : state) { + struct tuple *tuple = big_tuples[i++ % big_tuples.size()]; + sum += access_fields(tuple); + } + assert(sum > 0); +} +BENCHMARK(access_big_tuple_fields); + +static inline int +access_data(struct tuple *tuple) +{ + uint32_t out; + int sum = 0; + for (size_t j = 0; j <= index_count; j++) + sum += tuple_field_u32(tuple, j, &out); + return sum; +} + +static void +access_tuple_data(benchmark::State& state) +{ + size_t i = 0; + int64_t sum = 0; + for (auto _ : state) { + struct tuple *tuple = tuples[i++ % tuples.size()]; + access_data(tuple); + } + assert(sum == 0); +} +BENCHMARK(access_tuple_data); + +static void +access_tiny_tuple_data(benchmark::State& state) +{ + size_t i = 0; + int64_t sum = 0; + for (auto _ : state) { + struct tuple *tuple = tiny_tuples[i++ % tiny_tuples.size()]; + access_data(tuple); + } + assert(sum == 0); +} +BENCHMARK(access_tiny_tuple_data); + +static void +access_big_tuple_data(benchmark::State& state) +{ + size_t i = 0; + int64_t sum = 0; + for (auto _ : state) { + struct tuple *tuple = big_tuples[i++ % big_tuples.size()]; + access_data(tuple); + } + assert(sum == 0); +} +BENCHMARK(access_big_tuple_data); + +int main(int argc, char **argv) +{ + memory_init(); + fiber_init(fiber_c_invoke); + tuple_init(NULL); + + char *alloc = (char *)malloc(amount * 5 + amount * (amount - 1) * 2); + start = (char **)calloc(amount, sizeof(char *)); + end = (char **)calloc(amount, sizeof(char *)); + uint32_t data_size = index_count; + start[0] = alloc; + for (size_t i = 0; i < amount; i++) { + char *cur = start[i]; + cur = mp_encode_array(cur, ++data_size); + for (size_t j = 0; j < data_size; j++) + cur = mp_encode_uint(cur, j); + end[i] = cur; + if (i + 1 < amount) + start[i + 1] = cur; + } + + uint32_t fieldno0[] = {0}; + uint32_t fieldno1[] = {1}; + uint32_t fieldno2[] = {2, 3}; + uint32_t type1[] = {FIELD_TYPE_UNSIGNED}; + uint32_t type2[] = {FIELD_TYPE_UNSIGNED, FIELD_TYPE_UNSIGNED}; + box_key_def_t *key_defs[] = { + box_key_def_new(fieldno0, type1, 1), + box_key_def_new(fieldno1, type1, 1), + box_key_def_new(fieldno2, type2, 2)}; + box_tuple_format_t *format = box_tuple_format_new(key_defs, 3); + for (size_t i = 0; i < amount; i++) { + struct tuple *tuple = tuple_new(format, start[i], end[i]); + tuple_ref(tuple); + if (tuple->bsize <= UINT8_MAX) + tiny_tuples.push_back(tuple); + else + big_tuples.push_back(tuple); + tuples.push_back(tuple); + } + + ::benchmark::Initialize(&argc, argv); + if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1; + ::benchmark::RunSpecifiedBenchmarks(); + + free(alloc); + free(start); + free(end); + for (auto tuple: tuples) + tuple_unref(tuple); + + tuple_free(); + fiber_free(); + memory_free(); +} \ No newline at end of file diff --git a/src/box/alter.cc b/src/box/alter.cc index 075b79d33..8c65e7552 100644 --- a/src/box/alter.cc +++ b/src/box/alter.cc @@ -4538,7 +4538,7 @@ on_drop_sequence_data_rollback(struct trigger *trigger, void * /* event */) uint32_t id; if (tuple_field_u32(tuple, BOX_SEQUENCE_DATA_FIELD_ID, &id) != 0) return -1; - int64_t val; + int64_t val = 0; if (tuple_field_i64(tuple, BOX_SEQUENCE_DATA_FIELD_VALUE, &val) != 0) return -1; struct sequence *seq = sequence_by_id(id); -- 2.17.1