Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1m9Zp3-0002Kl-Mb for pgsql-hackers@arkaria.postgresql.org; Fri, 30 Jul 2021 21:13:37 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1m9Zp1-0003lK-Qr for pgsql-hackers@arkaria.postgresql.org; Fri, 30 Jul 2021 21:13:35 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1m9Zp1-0003lB-6h for pgsql-hackers@lists.postgresql.org; Fri, 30 Jul 2021 21:13:35 +0000 Received: from mail-ej1-x62c.google.com ([2a00:1450:4864:20::62c]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1m9Zox-0003HP-6V for pgsql-hackers@lists.postgresql.org; Fri, 30 Jul 2021 21:13:34 +0000 Received: by mail-ej1-x62c.google.com with SMTP id qk33so19073014ejc.12 for ; Fri, 30 Jul 2021 14:13:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=enterprisedb.com; s=google; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=W2257nGI38FQXWxbKUnCMcpoLvcVS2eeMf2ewb+qMOY=; b=fng7IjcakJJJ1uz1oOYbM4s+d20QwOQyrGVlR6BGqFzt8zAM+rKL9RxWPNF2dxiom0 /XH7uI8nlxOu67eIthOOb6529uNCYfawyyqshvYOURDKJPQGl45KCThQXGf/cRiZcnXh nCHPytPmzDpsbuOUMO1a8X7deaLa/t5cxX/HLzh9HZVDZAVhrhJvkH6oNTg91BBjyiB0 9Vph76F6a6EOj9TOmt48wP3UyWeTJy/ZlU+sye4oKzmABor6oM7cV5/JXfRU5nvGHTc5 ospqnm6yBM3VXOkRN2/2oypd496vU7w31QVR9Bo2utCWDdT3YwdMeQ76qAj8GZ8owwBy b8gA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=W2257nGI38FQXWxbKUnCMcpoLvcVS2eeMf2ewb+qMOY=; b=cL2Gs/TiKFoerE0rzWSngO9b6X9SeP2gFObuSbY9pKGyN4C13vNa7ETMgVx64mHWkm mRRM0NSfQx1W7wEUnD1t/v11t4XW5oc78RiReioK4MDenxKoy90APFBBa30xuJQh5rSY 6EmmDbFvUGYx2FR20iTYef26Fbpk+jr2g+Za3JOoMxqatFHqAFmmkWvy8S1XvEgcjRLb LRrPuZbVILmxyqkxY5phDdq7mErLJ2pPqqcWxs3I+nKE/SWpWSAOflyjTn9st0+fV0Nm 2tb0OfI/v3mAnwPReV0cd8EmbcYQ/t5Y30ReaN+BCg3pAL6FWWm/2UPlVqQZgnAhdYaJ g7Sw== X-Gm-Message-State: AOAM53269Mljnkicp4lzmEkOXmGGSZHWOYwm5PX96AyC9FJHgy82Jalt KZd+CnhzU5OHCg2zSdVDzMTJ6tX4cKGHZqDSEU3S6llU+w7RDd3YF/npHR8LKHLi6PWAEFCLISj 4oyhOPW5hI9NBZRHEoVH+zTjrkAT1aQx73QWWw2CLa0osRzXuUifUz1riSwg5oPfnJIB/yAUwau /eL/uJ0vPCuFq6mgvx9UBk19zuZU3i7hz5nSvcs7PTN9JZEV3aMw6igDD8pfrY/k3EQFopic/Lf apeYCTbpOEmAzHHymXIuhPSB3+rTLdPXyl5X7D9jOY61oSTu2j0ug== X-Google-Smtp-Source: ABdhPJw0ztZ6xIMHuwmBsd4Lvx/Tg6JlWdqqaLjnRgLPMOWogAIj/6fUtssjTwgdjSnFllUbdFg/Rg== X-Received: by 2002:a17:906:9c84:: with SMTP id fj4mr4680206ejc.438.1627679608950; Fri, 30 Jul 2021 14:13:28 -0700 (PDT) Received: from [10.137.0.18] (ip-86-49-254-183.net.upcbroadband.cz. [86.49.254.183]) by smtp.gmail.com with ESMTPSA id d23sm974883ejc.4.2021.07.30.14.13.28 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 30 Jul 2021 14:13:28 -0700 (PDT) Subject: Re: Use generation context to speed up tuplesorts To: Andres Freund , David Rowley , Tomas Vondra Cc: PostgreSQL Developers References: <20210730203853.utjj43f6zzn5e2hy@alap3.anarazel.de> From: Tomas Vondra Message-ID: Date: Fri, 30 Jul 2021 23:13:26 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.11.0 MIME-Version: 1.0 In-Reply-To: <20210730203853.utjj43f6zzn5e2hy@alap3.anarazel.de> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit X-CLOUD-SEC-AV-Info: enterprisedb,google_mail,monitor X-CLOUD-SEC-AV-Sent: true X-Gm-Spam: 0 X-Gm-Phishy: 0 List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On 7/30/21 10:38 PM, Andres Freund wrote: > Hi, > > On 2021-07-30 18:42:18 +1200, David Rowley wrote: >> While reviewing and benchmarking 91e9e89dc (Make nodeSort.c use Datum >> sorts for single column sorts), I noticed that we use a separate >> memory context to store tuple data and we just reset when we're done >> if the sort fits in memory, or we dump the tuples to disk in the same >> order they're added and reset the context when it does not. There is >> a little pfree() work going on via writetup_heap() which I think >> possibly could just be removed to get some additional gains. >> >> Anyway, this context that stores tuples uses the standard aset.c >> allocator which has the usual power of 2 wastage and additional >> overheads of freelists etc. I wondered how much faster it would go if >> I set it to use a generation context instead of an aset.c one. >> >> After running make installcheck to make the tenk1 table, running the >> attached tuplesortbench script, I get this: > >> So it seems to save quite a bit of memory getting away from rounding >> up allocations to the next power of 2. >> >> Performance-wise, there's some pretty good gains. (Results in TPS) > > Very nice! > Yes, very nice. I wouldn't have expected such significant difference, particularly in CPU usage. It's pretty interesting that it both reduces memory and CPU usage, I'd have guessed it's either one of the other. > > I wonder if there's cases where generation.c would regress performance > over aset.c due to not having an initial / "keeper" block? > Not sure. I guess such workload would need to allocate and free a single block (so very little memory) very often. I guess that's possible, but I'm not aware of a place doing that very often. Although, maybe decoding could do that for simple (serial) workload. I'm not opposed to adding a keeper block to Generation, similarly to what was discussed for Slab not too long ago. > >> The patch is just a simple 1-liner at the moment. I likely do need to >> adjust what I'm passing as the blockSize to GenerationContextCreate(). >> Maybe a better number would be something that's calculated from >> work_mem, e.g Min(ALLOCSET_DEFAULT_MAXSIZE, ((Size) work_mem) * 64)) >> so that we just allocate at most a 16th of work_mem per chunk, but not >> bigger than 8MB. I don't think changing this will affect the >> performance of the above very much. > > I think it's bad that both genereration and slab don't have internal > handling of block sizes. Needing to err on the size of too big blocks to > handle large amounts of memory well, just so the contexts don't need to > deal with variably sized blocks isn't a sensible tradeoff. > Well, back then it seemed like a sensible trade off to me, but I agree it may have negative consequences. I'm not opposed to revisiting this. > I don't think it's acceptable to use ALLOCSET_DEFAULT_MAXSIZE or > Min(ALLOCSET_DEFAULT_MAXSIZE, ((Size) work_mem) * 64) for > tuplesort.c. There's plenty cases where we'll just sort a handful of > tuples, and increasing the memory usage of those by a factor of 1024 > isn't good. The Min() won't do any good if a larger work_mem is used. > > Nor will it be good to use thousands of small allocations for a large > in-memory tuplesort just because we're concerned about the initial > allocation size. Both because of the allocation overhead, but > importantly also because that will make context resets more expensive. > True. > To me this says that we should transplant aset.c's block size growing > into generation.c. > Yeah, maybe. > > There is at least one path using tuplecontext that reaches code that > could end up freeing memory to a significant enough degree to care about > generation.c effectively not using that memory: > tuplesort_putdatum()->datumCopy()->EOH_flatten_into() > On a quick look I didn't find any expanded record user that frees > nontrivial amounts of memory, but I didn't look all that carefully. > Not sure, I'm not familiar with EOH_flatten_into or expanded records. But I wonder if there's some sort of metric that we could track in Generation and use it to identify "interesting" places. regards -- Tomas Vondra EnterpriseDB: http://www.enterprisedb.com The Enterprise PostgreSQL Company