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 1rxYtT-009hGw-3C for pgsql-hackers@arkaria.postgresql.org; Thu, 18 Apr 2024 21:02: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 1rxYtR-00A6Rs-QP for pgsql-hackers@arkaria.postgresql.org; Thu, 18 Apr 2024 21:02: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 1rxYtR-00A6Rk-Fg for pgsql-hackers@lists.postgresql.org; Thu, 18 Apr 2024 21:02:05 +0000 Received: from mail-io1-xd35.google.com ([2607:f8b0:4864:20::d35]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1rxYtO-001gaj-Ai for pgsql-hackers@lists.postgresql.org; Thu, 18 Apr 2024 21:02:04 +0000 Received: by mail-io1-xd35.google.com with SMTP id ca18e2360f4ac-7da382f57a5so29114039f.1 for ; Thu, 18 Apr 2024 14:02:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1713474121; x=1714078921; darn=lists.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=nRfWPifW4kCe+b+/dgBsZQWlbJA7eFTwTpGiEzozJyE=; b=YoUfzS8a0R8FUZ2GrRrQMZREDXnL3DtCG1Mg3a5Ctboc9zy4pklTd/AcSoQTjC4fnw m6FiW1pBFC/dOvvFs/36TjZvY7JcS6WLxmzJJGdPWnbMZRCI4kj9yquIz46pS6UX64yU A41iq/Ap3SENiLPeDHg+3isNjE16UZq21eSMQTe5+rDaoTZmjz/dy5fM9e6w0eDjUrfM uVPYKN4/ltt2Ivc9EwIeE8EVOOiBEyrpBtGqFLzGX824jXOD0ZV7y3L2IDb5p/dhL+5S 27NfeAN9AjWli2mMBQmET/kUqam0Vb8APKA4uri2zoKHztQ5cSw6j7W0Nnw4MfHlZkLi xctg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1713474121; x=1714078921; 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=nRfWPifW4kCe+b+/dgBsZQWlbJA7eFTwTpGiEzozJyE=; b=rf3qJ8qqUTQEw+/2R88Ze1LUySgNWIKY4/qBKRUbCYmiwRqDqZyN7ZTpTIkLwwWJG9 uVBtNQqBXuQ/QgcWwOxtYYVM62hKsZ0Cv+Ehq2W2fdRlBR8PJUPA/27LBbdvmyeSIadJ gWxYMlBRfPz2FfZ8HILCFLfclsHnfkaiH5jubrFo2EZXrU3szBK8RkyKFkmGvfz0BJgQ joIECI7YUC1O2GJ01Sy0hyofxdw5Fp/y/VOwoRJkCQc++x5AAwuBM4dRAaabe6BRUCSL OVro3UtIp6plLoJmvJe4Eim9wfDp8ppxiORifGupZuLimRkg7nEboJoQwHerT+NvlAuh azhQ== X-Forwarded-Encrypted: i=1; AJvYcCW7+nNcI1f4NuaxTA4VrNm4GsjsNQ4O5lkYrfpvJZUL0llPotgnwZNbJKGC/PpxJucNtPcI3gXKSngVv0weAKpD2sKuaXX+tO5m2pxn7g99eNP9 X-Gm-Message-State: AOJu0YyqzpySEXisZY6sIglSAnKTbdiV0BNZdwdqgNczosOPoYrSce2U RBcGtDPJ92CYwD0J3CqQb5ACp2RQbrMaXsMDfJlb5Z0bQhrw75HU X-Google-Smtp-Source: AGHT+IGyTwWqKqCdpnyibTrLxLW3y8hDhiyRO/VJlcJEdLszQv1E06mIZ24P9IXWEFwjPKhmF3Q6Ig== X-Received: by 2002:a6b:d904:0:b0:7d9:6351:4ef3 with SMTP id r4-20020a6bd904000000b007d963514ef3mr451267ioc.5.1713474120778; Thu, 18 Apr 2024 14:02:00 -0700 (PDT) Received: from nathanxps13 (162-195-168-172.lightspeed.stlsmo.sbcglobal.net. [162.195.168.172]) by smtp.gmail.com with ESMTPSA id bp15-20020a056638440f00b0048495eee32asm641041jab.3.2024.04.18.14.01.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 18 Apr 2024 14:02:00 -0700 (PDT) Date: Thu, 18 Apr 2024 16:01:58 -0500 From: Nathan Bossart To: "Devulapalli, Raghuveer" Cc: "Shankaran, Akash" , Tom Lane , David Rowley , Ants Aasma , Alvaro Herrera , "Amonson, Paul D" , Andres Freund , Noah Misch , Matthias van de Meent , "pgsql-hackers@lists.postgresql.org" Subject: Re: Popcount optimization using AVX512 Message-ID: <20240418210158.GA3776258@nathanxps13> References: <20240406194101.GA533391@nathanxps13> <2999492.1712536932@sss.pgh.pa.us> <20240408012332.GA1351547@nathanxps13> <20240408013002.GA1352058@nathanxps13> <3010179.1712540139@sss.pgh.pa.us> <20240418024459.GA3385227@nathanxps13> <20240418195346.GA3506520@nathanxps13> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="bg08WKrSYDhXBjb5" Content-Disposition: inline In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --bg08WKrSYDhXBjb5 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Thu, Apr 18, 2024 at 08:24:03PM +0000, Devulapalli, Raghuveer wrote: >> This seems to contradict the note about doing step 3 at any point, and >> given step 1 is the OSXSAVE check, I'm not following what this means, >> anyway. > > It is recommended that you run the xgetbv code before you check for cpu > features avx512-popcnt and avx512-bw. The way it is written now is the > opposite order. I would also recommend splitting the cpuid feature check > for avx512popcnt/avx512bw and xgetbv section into separate functions to > make them modular. Something like: > > static inline > int check_os_avx512_support(void) > { > // (1) run cpuid leaf 1 to check for xgetbv instruction support: > unsigned int exx[4] = {0, 0, 0, 0}; > __get_cpuid(1, &exx[0], &exx[1], &exx[2], &exx[3]); > if ((exx[2] & (1 << 27)) == 0) /* xsave */ > return false; > > /* Does XGETBV say the ZMM/YMM/XMM registers are enabled? */ > return (_xgetbv(0) & 0xe0) == 0xe0; > } > >> I'm also wondering if we need to check that (_xgetbv(0) & 0xe6) == 0xe6 >> instead of just (_xgetbv(0) & 0xe0) != 0, as the status of the lower >> half of some of the ZMM registers is stored in the SSE and AVX state >> [0]. I don't know how likely it is that 0xe0 would succeed but 0xe6 >> wouldn't, but we might as well make it correct. > > This is correct. It needs to check all the 3 bits (XMM/YMM and ZMM). The > way it is written is now is in-correct. Thanks for the feedback. I've attached an updated patch. -- Nathan Bossart Amazon Web Services: https://aws.amazon.com --bg08WKrSYDhXBjb5 Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v2-0001-osxsave.patch" From d20b19804a17d9f6eab1d40de7e9fb10488ac6b0 Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Thu, 18 Apr 2024 15:57:56 -0500 Subject: [PATCH v2 1/1] osxsave --- src/port/pg_popcount_avx512_choose.c | 89 +++++++++++++++++++--------- 1 file changed, 60 insertions(+), 29 deletions(-) diff --git a/src/port/pg_popcount_avx512_choose.c b/src/port/pg_popcount_avx512_choose.c index ae3fa3d306..009f94909a 100644 --- a/src/port/pg_popcount_avx512_choose.c +++ b/src/port/pg_popcount_avx512_choose.c @@ -34,27 +34,47 @@ #ifdef TRY_POPCNT_FAST /* - * Returns true if the CPU supports the instructions required for the AVX-512 - * pg_popcount() implementation. + * Does CPUID say there's support for XSAVE instructions? */ -bool -pg_popcount_avx512_available(void) +static inline bool +xsave_available(void) { unsigned int exx[4] = {0, 0, 0, 0}; - /* Does CPUID say there's support for AVX-512 popcount instructions? */ -#if defined(HAVE__GET_CPUID_COUNT) - __get_cpuid_count(7, 0, &exx[0], &exx[1], &exx[2], &exx[3]); -#elif defined(HAVE__CPUIDEX) - __cpuidex(exx, 7, 0); +#if defined(HAVE__GET_CPUID) + __get_cpuid(1, &exx[0], &exx[1], &exx[2], &exx[3]); +#elif defined(HAVE__CPUID) + __cpuid(exx, 1); #else #error cpuid instruction not available #endif - if ((exx[2] & (1 << 14)) == 0) /* avx512-vpopcntdq */ - return false; + return (exx[2] & (1 << 27)) != 0; /* osxsave */ +} + +/* + * Does XGETBV say the ZMM registers are enabled? + * + * NB: Caller is responsible for verifying that xsave_available() returns true + * before calling this. + */ +static inline bool +zmm_regs_available(void) +{ +#ifdef HAVE_XSAVE_INTRINSICS + return (_xgetbv(0) & 0xe6) != 0xe6; +#else + return false; +#endif +} + +/* + * Does CPUID say there's support for AVX-512 popcount instructions? + */ +static inline bool +avx512_popcnt_available(void) +{ + unsigned int exx[4] = {0, 0, 0, 0}; - /* Does CPUID say there's support for AVX-512 byte and word instructions? */ - memset(exx, 0, sizeof(exx)); #if defined(HAVE__GET_CPUID_COUNT) __get_cpuid_count(7, 0, &exx[0], &exx[1], &exx[2], &exx[3]); #elif defined(HAVE__CPUIDEX) @@ -62,27 +82,38 @@ pg_popcount_avx512_available(void) #else #error cpuid instruction not available #endif - if ((exx[1] & (1 << 30)) == 0) /* avx512-bw */ - return false; + return (exx[2] & (1 << 14)) != 0; /* avx512-vpopcntdq */ +} - /* Does CPUID say there's support for XSAVE instructions? */ - memset(exx, 0, sizeof(exx)); -#if defined(HAVE__GET_CPUID) - __get_cpuid(1, &exx[0], &exx[1], &exx[2], &exx[3]); -#elif defined(HAVE__CPUID) - __cpuid(exx, 1); +/* + * Does CPUID say there's support for AVX-512 byte and word instructions? + */ +static inline bool +avx512_bw_available(void) +{ + unsigned int exx[4] = {0, 0, 0, 0}; + +#if defined(HAVE__GET_CPUID_COUNT) + __get_cpuid_count(7, 0, &exx[0], &exx[1], &exx[2], &exx[3]); +#elif defined(HAVE__CPUIDEX) + __cpuidex(exx, 7, 0); #else #error cpuid instruction not available #endif - if ((exx[2] & (1 << 26)) == 0) /* xsave */ - return false; + return (exx[1] & (1 << 30)) != 0; /* avx512-bw */ +} - /* Does XGETBV say the ZMM registers are enabled? */ -#ifdef HAVE_XSAVE_INTRINSICS - return (_xgetbv(0) & 0xe0) != 0; -#else - return false; -#endif +/* + * Returns true if the CPU supports the instructions required for the AVX-512 + * pg_popcount() implementation. + */ +bool +pg_popcount_avx512_available(void) +{ + return xsave_available() && + zmm_regs_available() && + avx512_popcnt_available() && + avx512_bw_available(); } #endif /* TRY_POPCNT_FAST */ -- 2.25.1 --bg08WKrSYDhXBjb5--