Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1roW2Y-001vGo-M2 for pgsql-hackers@arkaria.postgresql.org; Sun, 24 Mar 2024 22:10:07 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1roW2X-00FpOd-0C for pgsql-hackers@arkaria.postgresql.org; Sun, 24 Mar 2024 22:10:05 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1roW2W-00FpOV-Jr for pgsql-hackers@lists.postgresql.org; Sun, 24 Mar 2024 22:10:05 +0000 Received: from mail-il1-x131.google.com ([2607:f8b0:4864:20::131]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1roW2R-006IGS-IE for pgsql-hackers@postgresql.org; Sun, 24 Mar 2024 22:10:04 +0000 Received: by mail-il1-x131.google.com with SMTP id e9e14a558f8ab-3685ef364d8so18396125ab.2 for ; Sun, 24 Mar 2024 15:09:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1711318197; x=1711922997; darn=postgresql.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=QW1y39p2BLOYsNQvBIT/6JFUVILHzOtshQj9uxaXpDg=; b=GekakF22h+yXD/MO0VW29dO4z7zTYHOU2433YQMnNyDHJzO81dljlexNiyziHvM2Nd 6FvBpT3wLU9vkqD4FxNlByAb7HP+EdNEMJKV0u8cWphFu+9K72/CKI9JkoApzXRKtus+ loGyhpq0afLzy4Sk0ks6gWX4UZddUXc/WsKAOY2Gq1D+aBjIfZpmPXjocAU2nWwb7ZeA rn9EKNd8y8ZAfz2f/lnFW9y/lpJpIzE7vDriQUkvY7XsdyKU3yli2uUYEoqm4k+eSzab FemIuGTwFjY9D2tizY3nt10uXtpN/z4qaGMRYXKaye50TwWC83DM5fI/Sz6wuDeDd5PI aAdQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1711318197; x=1711922997; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=QW1y39p2BLOYsNQvBIT/6JFUVILHzOtshQj9uxaXpDg=; b=WMKOAU9gDBKPWor24qdxDkfxIJISlmDWEchCV+dnqQfR9iJ6DOYlFtbIn6c0OPcQnv cpwfD5A+ojwYupCEHNQ2hm8Cv921H0LZheunSb/QA3B+/Hb5C3cF42jFFQ9c+HyvnBi3 +8kLXyQbftdZvsw3IdyUr2rohKrdcnPwqbDjn3BI42cZqRTniuWpxnNASSZ2Y+nLfOdt Zmq/dr+CXP4nJQPTiEHjLRQAviwoe/1XGujczIJ2O3875ASNFm5Jl9fs/pc5CaQd01L5 L3wIf7Zt8Tg9vvsomtmwiSgwmrSpfWc4+v4dQZ1V7sXDW9ZhNcAFkrTRuosF47A/Z/Cq K8Jw== X-Forwarded-Encrypted: i=1; AJvYcCVAWselECjLjLVUpIrtQ3SUVvW8/TqoSYSHRe15yp48ClvyP3W+lAi6DVpJFAYet3rW4K2j1tAFYZG4DHeR+W8OzL3382Geqgok5a3Y X-Gm-Message-State: AOJu0YyqjXdjZWQ4eiXoidpzbjycZZGxZ3hf/PRFlCb6PYAfmibZZvNX QhC4wR6hnuaoP4PjVxEAdUSV2zUgwF6dPLPGJeBOWRyJzjSeAOxu X-Google-Smtp-Source: AGHT+IEbX0ya006wsf+IBOvrdIBxZJW8pJ0A1SbyGJ2iA2DvCp3AHAZ3GKcTmjmhVlvvmKoNsbm2DQ== X-Received: by 2002:a92:c142:0:b0:368:6eac:3520 with SMTP id b2-20020a92c142000000b003686eac3520mr6033528ilh.17.1711318197056; Sun, 24 Mar 2024 15:09:57 -0700 (PDT) Received: from nathanxps13 (162-195-168-172.lightspeed.stlsmo.sbcglobal.net. [162.195.168.172]) by smtp.gmail.com with ESMTPSA id z1-20020a92d181000000b0036696282b0asm2007647ilz.10.2024.03.24.15.09.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 24 Mar 2024 15:09:56 -0700 (PDT) Date: Sun, 24 Mar 2024 17:09:54 -0500 From: Nathan Bossart To: John Naylor Cc: Ants Aasma , pgsql-hackers@postgresql.org Subject: Re: add AVX2 support to simd.h Message-ID: <20240324220954.GA2608761@nathanxps13> References: <20240319031601.GA828141@nathanxps13> <20240319163033.GA952199@nathanxps13> <20240320143116.GA1313857@nathanxps13> <20240320195513.GA1618413@nathanxps13> <20240321170944.GA1767527@nathanxps13> <20240321183823.GA1800896@nathanxps13> <20240324205317.GA2558640@nathanxps13> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="xHFwDpU9dbj6ez1V" Content-Disposition: inline In-Reply-To: <20240324205317.GA2558640@nathanxps13> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --xHFwDpU9dbj6ez1V Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Sun, Mar 24, 2024 at 03:53:17PM -0500, Nathan Bossart wrote: > Here's a new version of 0001 with some added #ifdefs that cfbot revealed > were missing. Sorry for the noise. cfbot revealed another silly mistake (forgetting to reset the "i" variable in the assertion path). That should be fixed in v8. -- Nathan Bossart Amazon Web Services: https://aws.amazon.com --xHFwDpU9dbj6ez1V Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v8-0001-pg_lfind32-add-overlap-code-for-remaining-element.patch" From f15d85844370aef8505559fc0f2db629b135a9e8 Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Wed, 20 Mar 2024 14:20:24 -0500 Subject: [PATCH v8 1/1] pg_lfind32(): add "overlap" code for remaining elements --- src/include/port/pg_lfind.h | 109 ++++++++++++++++++++++++------------ 1 file changed, 74 insertions(+), 35 deletions(-) diff --git a/src/include/port/pg_lfind.h b/src/include/port/pg_lfind.h index b8dfa66eef..f746aabbf9 100644 --- a/src/include/port/pg_lfind.h +++ b/src/include/port/pg_lfind.h @@ -80,6 +80,51 @@ pg_lfind8_le(uint8 key, uint8 *base, uint32 nelem) return false; } +#ifndef USE_NO_SIMD +/* + * pg_lfind32_helper + * + * Searches one 4-register-block of integers. The caller is responsible for + * ensuring that there are at least 4-registers-worth of integers remaining. + */ +static inline bool +pg_lfind32_helper(const Vector32 keys, uint32 *base) +{ + const uint32 nelem_per_vector = sizeof(Vector32) / sizeof(uint32); + Vector32 vals1, + vals2, + vals3, + vals4, + result1, + result2, + result3, + result4, + tmp1, + tmp2, + result; + + /* load the next block into 4 registers */ + vector32_load(&vals1, base); + vector32_load(&vals2, &base[nelem_per_vector]); + vector32_load(&vals3, &base[nelem_per_vector * 2]); + vector32_load(&vals4, &base[nelem_per_vector * 3]); + + /* compare each value to the key */ + result1 = vector32_eq(keys, vals1); + result2 = vector32_eq(keys, vals2); + result3 = vector32_eq(keys, vals3); + result4 = vector32_eq(keys, vals4); + + /* combine the results into a single variable */ + tmp1 = vector32_or(result1, result2); + tmp2 = vector32_or(result3, result4); + result = vector32_or(tmp1, tmp2); + + /* return whether there was a match */ + return vector32_is_highbit_set(result); +} +#endif /* ! USE_NO_SIMD */ + /* * pg_lfind32 * @@ -109,9 +154,9 @@ pg_lfind32(uint32 key, uint32 *base, uint32 nelem) bool assert_result = false; /* pre-compute the result for assert checking */ - for (i = 0; i < nelem; i++) + for (int j = 0; j < nelem; j++) { - if (key == base[i]) + if (key == base[j]) { assert_result = true; break; @@ -119,46 +164,40 @@ pg_lfind32(uint32 key, uint32 *base, uint32 nelem) } #endif - for (i = 0; i < tail_idx; i += nelem_per_iteration) + /* + * If there aren't enough elements for the SIMD code, jump to the standard + * one-by-one linear search code. + */ + if (nelem <= nelem_per_iteration) + goto one_by_one; + + /* + * Process as many elements as possible with a block of 4 registers. + */ + do { - Vector32 vals1, - vals2, - vals3, - vals4, - result1, - result2, - result3, - result4, - tmp1, - tmp2, - result; - - /* load the next block into 4 registers */ - vector32_load(&vals1, &base[i]); - vector32_load(&vals2, &base[i + nelem_per_vector]); - vector32_load(&vals3, &base[i + nelem_per_vector * 2]); - vector32_load(&vals4, &base[i + nelem_per_vector * 3]); - - /* compare each value to the key */ - result1 = vector32_eq(keys, vals1); - result2 = vector32_eq(keys, vals2); - result3 = vector32_eq(keys, vals3); - result4 = vector32_eq(keys, vals4); - - /* combine the results into a single variable */ - tmp1 = vector32_or(result1, result2); - tmp2 = vector32_or(result3, result4); - result = vector32_or(tmp1, tmp2); - - /* see if there was a match */ - if (vector32_is_highbit_set(result)) + if (pg_lfind32_helper(keys, &base[i])) { Assert(assert_result == true); return true; } - } + + i += nelem_per_iteration; + + } while (i < tail_idx); + + /* + * Process the last 'nelem_per_iteration' elements in the array with a + * 4-register block. This will cause us to check some of the elements + * more than once, but that won't affect correctness, and testing has + * demonstrated that this helps more cases than it harms. + */ + Assert(assert_result == pg_lfind32_helper(keys, &base[nelem - nelem_per_iteration])); + return pg_lfind32_helper(keys, &base[nelem - nelem_per_iteration]); + #endif /* ! USE_NO_SIMD */ +one_by_one: /* Process the remaining elements one at a time. */ for (; i < nelem; i++) { -- 2.25.1 --xHFwDpU9dbj6ez1V--