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 AC46170349; Fri, 22 Oct 2021 16:04:14 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org AC46170349 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1634907854; bh=MgTkSwNGxZQUN6uLmEsoTKsma//uZjMkKfvcHWZI12w=; h=To:Date:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=ltLukhDjS/BvS76gt9hxtB4AVNmMG6WDBipdbaZNixo+vnz18/X2fqq/ntWuQShg9 LNEfRDyGgwjBDxgvRhfbqYnOUVGocWHcCyJJhOIbRK/t23mk/bv2cxjCd8Bx2qkOGL JeJwHBlftu88xa+uB3tBcIvDxkafx5Bqina0emKI= Received: from smtp36.i.mail.ru (smtp36.i.mail.ru [94.100.177.96]) (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 15B2770349 for ; Fri, 22 Oct 2021 16:04:13 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 15B2770349 Received: by smtp36.i.mail.ru with esmtpa (envelope-from ) id 1mduDT-0000LD-Ka; Fri, 22 Oct 2021 16:04:12 +0300 To: Nikita Pettik , Igor Munkin Date: Fri, 22 Oct 2021 16:02:25 +0300 Message-Id: <20211022130225.6076-1-skaplun@tarantool.org> X-Mailer: git-send-email 2.31.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-7564579A: B8F34718100C35BD X-77F55803: 4F1203BC0FB41BD9C7814344C8C501C8A4649CC2A06649B6A97F49A0BDC630D4182A05F538085040DB37CAED39DC88699519B9765E3E2C847838840A3887DA33F35B330758867035 X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE723A0121E4B9CF535EA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F7900637389D8DDD54F43F7A8638F802B75D45FF36EB9D2243A4F8B5A6FCA7DBDB1FC311F39EFFDF887939037866D6147AF826D8C876EB10C4FBBBE4CE4D9F8EAE3EE8D6117882F4460429724CE54428C33FAD305F5C1EE8F4F765FCECADA55FE5B58BB7A471835C12D1D9774AD6D5ED66289B52BA9C0B312567BB23117882F44604297287769387670735201E561CDFBCA1751FBDFBBEFFF4125B51D2E47CDBA5A96583BA9C0B312567BB2376E601842F6C81A19E625A9149C048EE599709FD55CB46A67AAF5A6EB0CB4C2AD8FC6C240DEA7642DBF02ECDB25306B2B78CF848AE20165D0A6AB1C7CE11FEE364E7220B7C5505926136E347CC761E07C4224003CC836476EA7A3FFF5B025636E2021AF6380DFAD1A18204E546F3947CB11811A4A51E3B096D1867E19FE1407959CC434672EE6371089D37D7C0E48F6C8AA50765F790063757B1FBEA53BC6EDBEFF80C71ABB335746BA297DBC24807EABDAD6C7F3747799A X-C1DE0DAB: C20DE7B7AB408E4181F030C43753B8186998911F362727C414F749A5E30D975C36D3CF9385F5124E4F24CBE8F6A91391E097D18D4F5E9BC19C2B6934AE262D3EE7EAB7254005DCED4DF83050870D0EDA1E0A4E2319210D9B64D260DF9561598F01A9E91200F654B02272C4C079A4C8AD93EDB24507CE13387DFF0A840B692CF8 X-C8649E89: 4E36BF7865823D7055A7F0CF078B5EC49A30900B95165D3455049D7B43D89D64A31284CC41796FE48BED4D104B50E4FD4730FFEAE836C8F0E25D3A485FB58D0A1D7E09C32AA3244C3AF1C9E03984350ACF99C69197F0C4A0E3D93501275E802F927AC6DF5659F194 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojoAoFOtfvdI1zzjcqtAU7Ug== X-Mailru-Sender: 583F1D7ACE8F49BDE0FCA1347FF714A12875A296AD5EDF6E7C903FD5E5DE832D14DA969EB3B59FCD525762887713E5F1475755348978188EF9D3679FA3DE6E791CC59163FFD68303112434F685709FCF0DA7A0AF5A3A8387 X-Mras: Ok Subject: [Tarantool-patches] [PATCH] tuple: make tuple_bless() compilable 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: Sergey Kaplun via Tarantool-patches Reply-To: Sergey Kaplun Cc: tarantool-patches@dev.tarantool.org Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" tuple_bless() uses a tail call to ffi.gc() with return to the caller. This tail call replaces the current (tuple_bless) frame with the frame of the callee (ffi.gc). When JIT tries to compile return from `ffi.gc()` to the frame below it aborts the trace recording with the error "NYI: return to lower frame". This patch replaces the tail call with using additional local variable returned to the caller right after. --- Actually, this patch become possible thanks to Michael Filonenko and his benchmarks of TDG runs with jit.dump() enabled. After analysis of this dump we realize that tuple_bless is not compiled. This uncompiled chunk of code leads to the JIT cancer for all possible workflows that use tuple_bless() (i.e. tuple:update() and tuple:upsert()). This change is really trivial, but adds almost x2 improvement of performance for tuple:update()/upsert() scenario. Hope, that this patch will be a stimulus for including benchmarks of our forward products like TDG to routine performance running with the corresponding profilers dumps. Benchmarks: Before patch: Update: | Tarantool 2.10.0-beta1-90-g31594b427 | type 'help' for interactive help | tarantool> local t = {} | for i = 1, 1e6 do | table.insert(t, box.tuple.new{'abc', 'def', 'ghi', 'abc'}) | end | local clock = require"clock" | local S = clock.proc() | for i = 1, 1e6 do t[i]:update{{"=", 3, "xxx"}} end | return clock.proc() - S; | --- | - 4.208298872 Upsert: 4.158661731 After patch: Update: | Tarantool 2.10.0-beta1-90-g31594b427 | type 'help' for interactive help | tarantool> local t = {} | for i = 1, 1e6 do | table.insert(t, box.tuple.new{'abc', 'def', 'ghi', 'abc'}) | end | local clock = require"clock" | local S = clock.proc() | for i = 1, 1e6 do t[i]:update{{"=", 3, "xxx"}} end | return clock.proc() - S; | --- | - 2.357670738 Upsert: 2.334134195 Branch: https://github.com/tarantool/tarantool/tree/skaplun/gh-noticket-tuple-bless-compile src/box/lua/tuple.lua | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/box/lua/tuple.lua b/src/box/lua/tuple.lua index fa76f4f7f..73446ab22 100644 --- a/src/box/lua/tuple.lua +++ b/src/box/lua/tuple.lua @@ -98,7 +98,14 @@ local tuple_bless = function(tuple) -- overflow checked by tuple_bless() in C builtin.box_tuple_ref(tuple) -- must never fail: - return ffi.gc(ffi.cast(const_tuple_ref_t, tuple), tuple_gc) + -- XXX: If we use tail call (instead creating a new frame for + -- a call just replace the top one) here, then JIT tries + -- to compile return from `ffi.gc()` to the frame below. This + -- abort the trace recording with the error "NYI: return to + -- lower frame". So avoid tail call and use additional stack + -- slots (for the local variable and the frame). + local tuple_ref = ffi.gc(ffi.cast(const_tuple_ref_t, tuple), tuple_gc) + return tuple_ref end local tuple_check = function(tuple, usage) -- 2.31.0