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 1oLGHJ-0006yv-QD for pgsql-hackers@arkaria.postgresql.org; Tue, 09 Aug 2022 03:51: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 1oLGHI-0002T7-Mm for pgsql-hackers@arkaria.postgresql.org; Tue, 09 Aug 2022 03:51:36 +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 1oLGHI-0002SC-Bn for pgsql-hackers@lists.postgresql.org; Tue, 09 Aug 2022 03:51:36 +0000 Received: from mail-pg1-x532.google.com ([2607:f8b0:4864:20::532]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1oLGHF-0005Jc-RO for pgsql-hackers@postgresql.org; Tue, 09 Aug 2022 03:51:35 +0000 Received: by mail-pg1-x532.google.com with SMTP id f65so10295479pgc.12 for ; Mon, 08 Aug 2022 20:51:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc; bh=6emMTvPxV2bvvMWvNAcB9EKQYsES9fZZJ2CpYspiLOo=; b=bDVoEZTc4zn2yoNxzaLbu+2a0vqicipBNYL2snTqRY5XBHFKZmVtfsmuWGYJuwCaC3 g553uRa8yFnIW/3aPjE5yYbTILQDTnX8Y0osyO3eWyhYk/15vSxoDqjFdSQPTec3jpdu dpGYne49ziuIMUB6UYYkErEeiVPJGhyHVGfP0hUb42geoFOjHOZAjNZTKORSMfY8cpaw 20hsF+XKb/NH/KT68ihwg8fXUKoFDvBDlFyEhyyyRckr0cRofd2ViovSfZI8Pbn99s6G tvm0nVdwHbJygF86r6DydliEW5HSvjLKYhmBsHuAoU5h2Ie0242/HdpIlDelgM7R3Kee 8u4Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc; bh=6emMTvPxV2bvvMWvNAcB9EKQYsES9fZZJ2CpYspiLOo=; b=lklZgc1C9RJ5qAI2mTXwH90s4y06K3C6rycazBuo2T3v3RlC3maAoVLuDevlqm6IGx KwKvHmqFErgrD4zD/bzhcjADJn0rQRqUiWxN2R27YClCFR8k8xyXIyJu3k+Kv3wT6gMJ gc6cc9WtvowTR2jLGEWMZiKWnjxzsd2cHRbv+sAMVk4O8gtorkWw85Ntj1TLMFdwSpkW DqwafMem3t922xqiT7CXbUDRc6OcyazCqJSTCU7ozXoVYlQO0SiusPsO/qQK9VvToAqw VByH70pDloczbwbmQGHD1UVoY13UKNtGReoLWNLHAp/lgVxLZkvHbycw1oXETset0jdX DK7A== X-Gm-Message-State: ACgBeo0GHINCvFBYKXytVzFcESfh2q82xJ3bE4Fs7KBtiGfAWQFKZ3Nr TcHF43UJjbOsypxZVo5wS44= X-Google-Smtp-Source: AA6agR7n5alUf9eYbvH8crGBgb2gF+J+W2DTXfI/KJ5zrVJCnzu8N7PfGivq9Eiga/jIMftde4h2bg== X-Received: by 2002:a05:6a00:1581:b0:52f:a5bb:b9a0 with SMTP id u1-20020a056a00158100b0052fa5bbb9a0mr2098805pfk.80.1660017091785; Mon, 08 Aug 2022 20:51:31 -0700 (PDT) Received: from nathanxps13 ([50.54.155.70]) by smtp.gmail.com with ESMTPSA id a16-20020aa794b0000000b0052bae7b2af8sm9429721pfl.201.2022.08.08.20.51.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 08 Aug 2022 20:51:31 -0700 (PDT) Date: Mon, 8 Aug 2022 20:51:29 -0700 From: Nathan Bossart To: Masahiko Sawada Cc: John Naylor , Andres Freund , John Naylor , pgsql-hackers Subject: Re: optimize lookups in snapshot [sub]xip arrays Message-ID: <20220809035129.GA1440829@nathanxps13> References: <20220804221551.GA1090071@nathanxps13> <20220805202510.GA1208450@nathanxps13> <20220805220434.6h2aa7eww5rxird6@awork3.anarazel.de> <20220806181326.GA1216305@nathanxps13> <20220806212522.GA1221353@nathanxps13> <20220808223254.GA1393216@nathanxps13> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="4Ckj6UjgE2iN1+kY" Content-Disposition: inline In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --4Ckj6UjgE2iN1+kY Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Tue, Aug 09, 2022 at 10:57:44AM +0900, Masahiko Sawada wrote: > The patch looks good to me. One minor point is: Thanks for taking a look. > + * IDENTIFICATION > + * src/port/pg_lfind.h > > The path doesn't match to the actual file path, src/include/port/pg_lfind.h. Fixed in v10. -- Nathan Bossart Amazon Web Services: https://aws.amazon.com --4Ckj6UjgE2iN1+kY Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v10-0001-Introduce-optimized-routine-for-linear-searches-.patch" From ed80cfaf146f82b930ea09b8efc062cc4088d4b6 Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Wed, 3 Aug 2022 09:49:04 -0700 Subject: [PATCH v10 1/2] Introduce optimized routine for linear searches through an array of integers. If SSE2 is available, this function uses it to speed up the search. Otherwise, it uses a simple 'for' loop. This is a prerequisite for a follow-up commit that will use this function to optimize [sub]xip lookups in XidInMVCCSnapshot(), but it can be used anywhere that might benefit from such an optimization. It might be worthwhile to add an ARM-specific code path to this function in the future. Author: Nathan Bossart Reviewed by: Andres Freund, John Naylor, Bharath Rupireddy, Masahiko Sawada Discussion: https://postgr.es/m/20220713170950.GA3116318%40nathanxps13 --- src/include/port/pg_lfind.h | 69 +++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 src/include/port/pg_lfind.h diff --git a/src/include/port/pg_lfind.h b/src/include/port/pg_lfind.h new file mode 100644 index 0000000000..24de544f63 --- /dev/null +++ b/src/include/port/pg_lfind.h @@ -0,0 +1,69 @@ +/*------------------------------------------------------------------------- + * + * pg_lfind.h + * Optimized linear search routines. + * + * Copyright (c) 2022, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/include/port/pg_lfind.h + * + *------------------------------------------------------------------------- + */ +#ifndef PG_LFIND_H +#define PG_LFIND_H + +#include "port/simd.h" + +/* + * pg_lfind32 + * + * Returns true if there is an element in 'base' that equals 'key'. Otherwise, + * returns false. + */ +static inline bool +pg_lfind32(uint32 key, uint32 *base, uint32 nelem) +{ + uint32 i = 0; + + /* If possible, use SSE2 intrinsics to speed up the search. */ +#ifdef USE_SSE2 + const __m128i keys = _mm_set1_epi32(key); /* load 4 copies of key */ + uint32 iterations = nelem & ~0xF; /* round down to multiple of 16 */ + + for (; i < iterations; i += 16) + { + /* load the next 16 values into __m128i variables */ + const __m128i vals1 = _mm_loadu_si128((__m128i *) &base[i]); + const __m128i vals2 = _mm_loadu_si128((__m128i *) &base[i + 4]); + const __m128i vals3 = _mm_loadu_si128((__m128i *) &base[i + 8]); + const __m128i vals4 = _mm_loadu_si128((__m128i *) &base[i + 12]); + + /* perform the comparisons */ + const __m128i result1 = _mm_cmpeq_epi32(keys, vals1); + const __m128i result2 = _mm_cmpeq_epi32(keys, vals2); + const __m128i result3 = _mm_cmpeq_epi32(keys, vals3); + const __m128i result4 = _mm_cmpeq_epi32(keys, vals4); + + /* shrink the results into a single variable */ + const __m128i tmp1 = _mm_or_si128(result1, result2); + const __m128i tmp2 = _mm_or_si128(result3, result4); + const __m128i result = _mm_or_si128(tmp1, tmp2); + + /* see if there was a match */ + if (_mm_movemask_epi8(result) != 0) + return true; + } +#endif + + /* Process the remaining elements the slow way. */ + for (; i < nelem; i++) + { + if (key == base[i]) + return true; + } + + return false; +} + +#endif /* PG_LFIND_H */ -- 2.25.1 --4Ckj6UjgE2iN1+kY Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v10-0002-Optimize-linear-searches-in-XidInMVCCSnapshot.patch" From 28bc28d898afad0762c1966b21e9582294e8b101 Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Wed, 3 Aug 2022 09:59:28 -0700 Subject: [PATCH v10 2/2] Optimize linear searches in XidInMVCCSnapshot(). This change makes use of the recently-introduced optimized linear search routine to speed up searches through the [sub]xip arrays when possible, which should improve performance significantly when the arrays are large. Author: Nathan Bossart Reviewed by: Andres Freund, John Naylor, Bharath Rupireddy, Masahiko Sawada Discussion: https://postgr.es/m/20220713170950.GA3116318%40nathanxps13 --- src/backend/utils/time/snapmgr.c | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/src/backend/utils/time/snapmgr.c b/src/backend/utils/time/snapmgr.c index 5bc2a15160..9b504c9745 100644 --- a/src/backend/utils/time/snapmgr.c +++ b/src/backend/utils/time/snapmgr.c @@ -56,6 +56,7 @@ #include "datatype/timestamp.h" #include "lib/pairingheap.h" #include "miscadmin.h" +#include "port/pg_lfind.h" #include "storage/predicate.h" #include "storage/proc.h" #include "storage/procarray.h" @@ -2284,8 +2285,6 @@ RestoreTransactionSnapshot(Snapshot snapshot, void *source_pgproc) bool XidInMVCCSnapshot(TransactionId xid, Snapshot snapshot) { - uint32 i; - /* * Make a quick range check to eliminate most XIDs without looking at the * xip arrays. Note that this is OK even if we convert a subxact XID to @@ -2317,13 +2316,8 @@ XidInMVCCSnapshot(TransactionId xid, Snapshot snapshot) if (!snapshot->suboverflowed) { /* we have full data, so search subxip */ - int32 j; - - for (j = 0; j < snapshot->subxcnt; j++) - { - if (TransactionIdEquals(xid, snapshot->subxip[j])) - return true; - } + if (pg_lfind32(xid, snapshot->subxip, snapshot->subxcnt)) + return true; /* not there, fall through to search xip[] */ } @@ -2344,16 +2338,11 @@ XidInMVCCSnapshot(TransactionId xid, Snapshot snapshot) return false; } - for (i = 0; i < snapshot->xcnt; i++) - { - if (TransactionIdEquals(xid, snapshot->xip[i])) - return true; - } + if (pg_lfind32(xid, snapshot->xip, snapshot->xcnt)) + return true; } else { - int32 j; - /* * In recovery we store all xids in the subxact array because it is by * far the bigger array, and we mostly don't know which xids are @@ -2383,11 +2372,8 @@ XidInMVCCSnapshot(TransactionId xid, Snapshot snapshot) * indeterminate xid. We don't know whether it's top level or subxact * but it doesn't matter. If it's present, the xid is visible. */ - for (j = 0; j < snapshot->subxcnt; j++) - { - if (TransactionIdEquals(xid, snapshot->subxip[j])) - return true; - } + if (pg_lfind32(xid, snapshot->subxip, snapshot->subxcnt)) + return true; } return false; -- 2.25.1 --4Ckj6UjgE2iN1+kY--