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 1oC3HY-0005D7-1K for pgsql-hackers@arkaria.postgresql.org; Thu, 14 Jul 2022 18:09:48 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1oC3HV-0007hi-Tb for pgsql-hackers@arkaria.postgresql.org; Thu, 14 Jul 2022 18:09:45 +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 1oC3HV-0007hZ-IH for pgsql-hackers@lists.postgresql.org; Thu, 14 Jul 2022 18:09:45 +0000 Received: from mail-pg1-x52b.google.com ([2607:f8b0:4864:20::52b]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1oC3HS-0005Yz-7l for pgsql-hackers@postgresql.org; Thu, 14 Jul 2022 18:09:45 +0000 Received: by mail-pg1-x52b.google.com with SMTP id 72so2311549pge.0 for ; Thu, 14 Jul 2022 11:09:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:content-transfer-encoding:in-reply-to; bh=Ce1rkwK/Ahjnms5vQ8qPdsDgO4hzFvNo9TI464sgeB4=; b=iW+blsxnvntkwFQLq5ZDmkXECpM4R/8IZM/FxjLZbm9whCZDa9mjpW7lNngVE/rp1l t7eiOMRHjfLrUqR4VK5LG/nraKEnmuf4U1puXdQQABqqfhGV/XlTN0hZ8LmWKneCcpGT 2/70NYyYiktsWNuDvOF3BycMh1Z7P6lvwRvL+1CFX7jZdDlK69O6qF70QhfkBPcFUgf9 eZVH2LfI3TZIyN6Ul3EfEpxdQ6LVtkPwQ8UB2y4rUeLzI4p/zIB4w5nK0vehDgnxVMmF 6Pd+w8GoA+Otp5v9wR7Os561HY1g7R1oFaM2GvpKkegMUc5qh5q2cwCjVXQ9cmufKFWb 5vxg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:content-transfer-encoding :in-reply-to; bh=Ce1rkwK/Ahjnms5vQ8qPdsDgO4hzFvNo9TI464sgeB4=; b=Hks7MLqPoOdDWvGhU6CTfH0M1EZAH0mlLv3zkD0NI3a+wwM3TS2Gr63cBwLyjHE1gS gf2J4KNuQSnRO/E6Goq622zv8V70WPn1/Jo7wIHqQzIduS6yBVTK1g/FK7nJ4GMnuqYQ WFC+UXRnOJYlQ/t7u5+ELYTxYAIlgP20+Zr/NGo7vW7/SDXvQcEX+ODcoS48R+V3nEE7 3gXQMwplqxiicGJomvaXJuN22pxTTjXeXEXEDcNFDBTr4pG646KanaeWKg80frHAyTbK xICCP3jywRslkPXNXrdMgvUX199kBYVsQ9fr6hu8vUoUQC4iLFrKWH+KEamw6sW/o6xV dvcw== X-Gm-Message-State: AJIora/up2f6IGKHJV72ag+h/m/BiM8dtz/tOKu1OZBotFH1rvxY90P0 Q6y12oAhJTWzmqfC3qZlTRQ= X-Google-Smtp-Source: AGRyM1tcbfSxpcNSwJYNmNGiaFZzPKzy4u9gk6/ei8PV5fvCdNi7tUxotWOY1jQVPsI9qaVTuJJC0A== X-Received: by 2002:a63:cf52:0:b0:40d:fb07:a793 with SMTP id b18-20020a63cf52000000b0040dfb07a793mr9031215pgj.576.1657822179584; Thu, 14 Jul 2022 11:09:39 -0700 (PDT) Received: from nathanxps13 ([50.54.155.70]) by smtp.gmail.com with ESMTPSA id j5-20020a637a45000000b00419d02e580fsm462478pgn.47.2022.07.14.11.09.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Jul 2022 11:09:39 -0700 (PDT) Date: Thu, 14 Jul 2022 11:09:38 -0700 From: Nathan Bossart To: Bharath Rupireddy Cc: PostgreSQL-development Subject: Re: optimize lookups in snapshot [sub]xip arrays Message-ID: <20220714180938.GA3125784@nathanxps13> References: <20220713170950.GA3116318@nathanxps13> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Hi Bharath, Thanks for taking a look. On Thu, Jul 14, 2022 at 03:10:56PM +0530, Bharath Rupireddy wrote: > Aren't these snapshot arrays always sorted? I see the following code: > > /* sort so we can bsearch() */ > qsort(snapshot->xip, snapshot->xcnt, sizeof(TransactionId), xidComparator); > > /* sort so we can bsearch() later */ > qsort(snap->subxip, snap->subxcnt, sizeof(TransactionId), xidComparator); AFAICT these arrays are sorted in limited cases, such as pg_current_snapshot() and logical replication. GetSnapshotData() does not appear to sort them, so I don't think we can always assume they are sorted. In the previous thread, Tomas analyzed simply sorting the arrays [0] and found that it provided much less improvement compared to the hash table approach, so I have not seriously considered it here. > If the ordering isn't an invariant of these snapshot arrays, can we > also use the hash table mechanism for all of the snapshot arrays > infrastructure rather than qsort+bsearch in a few places and hash > table for others? Unless there is demonstrable benefit in doing so for the few places that sort the arrays, I'm ѕkeptical it's worth the complexity. This patch is targeted to XidInMVCCSnapshot(), which we can demonstrate has clear impact on TPS for some workloads. > + * The current value worked well in testing, but it's still mostly a guessed-at > + * number that might need updating in the future. > + */ > +#define XIP_HASH_MIN_ELEMENTS (128) > + > > Do you see a regression with a hash table for all the cases? Why can't > we just build a hash table irrespective of these limits and use it for > all the purposes instead of making it complex with different > approaches if we don't have measurable differences in the performance > or throughput? I performed the same tests as before with a variety of values. Here are the results: writers HEAD 1 16 32 64 128 ------------------------------------ 16 659 698 678 659 665 664 32 645 661 688 657 649 663 64 659 656 653 649 663 692 128 641 636 639 679 643 716 256 619 641 619 643 653 610 512 530 609 582 602 605 702 768 469 610 608 551 571 582 1000 367 610 538 557 556 577 I was surpised to see that there really wasn't a regression at the low end, but keep in mind that this is a rather large machine and a specialized workload for generating snapshots with long [sub]xip arrays. That being said, there really wasn't any improvement at the low end, either. If we always built a hash table, we'd be introducing more overhead and memory usage in return for approximately zero benefit. My intent was to only take on the overhead in cases where we believe it might have a positive impact, which is why I picked the somewhat conservative value of 128. If the overhead isn't a concern, it might be feasible to always make [sub]xip a hash table. > +static inline bool > +XidInXip(TransactionId xid, TransactionId *xip, uint32 xcnt, > + xip_hash_hash **xiph) > > + /* Make sure the hash table is built. */ > + if (*xiph == NULL) > + { > + *xiph = xip_hash_create(TopTransactionContext, xcnt, NULL); > + > + for (int i = 0; i < xcnt; i++) > > Why create a hash table on the first search? Why can't it be built > while inserting or creating these snapshots? Basically, instead of the > array, can these snapshot structures be hash tables by themselves? I > know this requires a good amount of code refactoring, but worth > considering IMO as it removes bsearch thus might improve the > performance further. The idea is to avoid the overhead unless something actually needs to inspect these arrays. [0] https://postgr.es/m/057a9a95-19d2-05f0-17e2-f46ff20e9b3e%402ndquadrant.com -- Nathan Bossart Amazon Web Services: https://aws.amazon.com