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 1stuvI-002fmC-GK for pgsql-hackers@arkaria.postgresql.org; Thu, 26 Sep 2024 20:17:13 +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 1stuvH-00Dhh5-1o for pgsql-hackers@arkaria.postgresql.org; Thu, 26 Sep 2024 20:17:11 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1stuvG-00Dhdt-Jd for pgsql-hackers@lists.postgresql.org; Thu, 26 Sep 2024 20:17:10 +0000 Received: from mail-io1-xd2e.google.com ([2607:f8b0:4864:20::d2e]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1stuvD-001Cx0-MG for pgsql-hackers@postgresql.org; Thu, 26 Sep 2024 20:17:09 +0000 Received: by mail-io1-xd2e.google.com with SMTP id ca18e2360f4ac-82ceab75c27so71810939f.1 for ; Thu, 26 Sep 2024 13:17:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1727381826; x=1727986626; darn=postgresql.org; h=content-disposition:mime-version:message-id:subject:to:from:date :from:to:cc:subject:date:message-id:reply-to; bh=2kByIx3LmG5DcQ0Hdm/O2pPWrywnShJA1Ci2DDRaIJo=; b=AIpCUiChrOeJNKY4VveX/98L25uuoDNnZKFPRuVycNw0sTpD+mnS8Dc525CTw2tCjq IjN34FNZcnZ7/abmGntUwDLhYdwWfWptD3ukDc06woEMSRdvEmShPp66oe6l1Tkccc54 L4rV1yf3f5FXoL+9BYGGvsWVZW5Kzz1NfIjepasjvV8BBwdSPeaUmB6enysNphCOva0p UbVYzptfzZZYYARoPzAucavBBvVkx7/mSOAFq9uPlGOcHMt1qTU/vagqoUwvG0tkfcS5 t64ehGaBHG+AnFucSpcSTQNY6hy0Ig7iP/JTHJhxMGq9ALVzm1iKEgkwZsEcPeLiCE+g XR1g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727381826; x=1727986626; h=content-disposition:mime-version:message-id:subject:to:from:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=2kByIx3LmG5DcQ0Hdm/O2pPWrywnShJA1Ci2DDRaIJo=; b=j2o38bXAL9+bye2MRaEwSNH9PznPdbZEr1aRMaE7N48wL5KG/8Jz2+eswEZa/eGwHA IRNKt577XShnkjGuVtvsOTlK57NWip2clTbbS2+cVEJJjTdHrx52ToNUXFr6NCts1+v1 cMWD4tMd6zLLewyeLTii7KLYe1I6MJMnOCGwL/ulizdj/XYUjw0cqGyNlBqA5f9loK6r fYbiiZFLIwCcqoPAkKL1hm2WKG3PSNE/ixWMa8XqnH/g5vTmoTgN9GmCXDDAfU8BrtX4 rwOD0ZDzwAJmo+pjLiuuf1MDFpFfwGp/A0gKX2qi7u45QZBPoxUvi7ry7+4NdTSuGkD4 7JGw== X-Gm-Message-State: AOJu0YzPUbWInQ+Z7i51EIX843SJ6jX7DLHpu9jP8o1Jd+mrPQU3R4vY V4IrZdmhTracUz4cTkbrg6hBNhRzk8TklZKM5rVzXwPZJdFiv90aEF38Dw== X-Google-Smtp-Source: AGHT+IFyiDLeFc1z+/q2p/VOILKkQJk5HniXk/WcEQHLAnHZZJZ0TED8hKZuXn3c/8Q/j+AV7k3Nag== X-Received: by 2002:a05:6602:6015:b0:82a:31d4:1aab with SMTP id ca18e2360f4ac-834932741fdmr105320939f.14.1727381826182; Thu, 26 Sep 2024 13:17:06 -0700 (PDT) Received: from nathan (162-195-168-172.lightspeed.stlsmo.sbcglobal.net. [162.195.168.172]) by smtp.gmail.com with ESMTPSA id ca18e2360f4ac-834936e2583sm10407939f.25.2024.09.26.13.17.05 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 26 Sep 2024 13:17:05 -0700 (PDT) Date: Thu, 26 Sep 2024 15:17:03 -0500 From: Nathan Bossart To: pgsql-hackers@postgresql.org Subject: micro-optimize nbtcompare.c routines Message-ID: MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="STuNuYHiUS+fxQmC" Content-Disposition: inline List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --STuNuYHiUS+fxQmC Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Here's a patch that adjusts several routines in nbtcompare.c and related files to use the branchless integer comparison functions added in commit 6b80394. It's probably unlikely this produces a measurable benefit (at least I've been unable to find any in my admittedly-limited testing), but in theory it should save a cycle here and there. I was hoping that this would trim many lines of code, but maintaining the STRESS_SORT_INT_MIN stuff eats up most of what we save. Anyway, I don't feel too strongly about this patch, but I went to the trouble of writing it, and so I figured I'd post it. -- nathan --STuNuYHiUS+fxQmC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="v1-0001-micro-optimize-nbtcompare.c-routines.patch" From bd2e1eb92b28cf855b529b09813f1b09084c7cfc Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Thu, 26 Sep 2024 15:03:32 -0500 Subject: [PATCH v1 1/1] micro-optimize nbtcompare.c routines --- src/backend/access/nbtree/nbtcompare.c | 162 ++++++++++++------------- src/backend/storage/page/itemptr.c | 18 +-- src/backend/utils/sort/tuplesort.c | 21 ++-- 3 files changed, 96 insertions(+), 105 deletions(-) diff --git a/src/backend/access/nbtree/nbtcompare.c b/src/backend/access/nbtree/nbtcompare.c index 1c72867c84..2df0c5dbe0 100644 --- a/src/backend/access/nbtree/nbtcompare.c +++ b/src/backend/access/nbtree/nbtcompare.c @@ -57,17 +57,16 @@ #include +#include "common/int.h" #include "utils/fmgrprotos.h" #include "utils/sortsupport.h" -#ifdef STRESS_SORT_INT_MIN -#define A_LESS_THAN_B INT_MIN -#define A_GREATER_THAN_B INT_MAX -#else -#define A_LESS_THAN_B (-1) -#define A_GREATER_THAN_B 1 -#endif - +#define STRESS_SORT_INT_MIN_CMP(a, b) \ +( \ + ((a) > (b)) ? INT_MAX : \ + ((a) < (b)) ? INT_MIN : \ + 0 \ +) Datum btboolcmp(PG_FUNCTION_ARGS) @@ -84,7 +83,11 @@ btint2cmp(PG_FUNCTION_ARGS) int16 a = PG_GETARG_INT16(0); int16 b = PG_GETARG_INT16(1); - PG_RETURN_INT32((int32) a - (int32) b); +#ifdef STRESS_SORT_INT_MIN + PG_RETURN_INT32(STRESS_SORT_INT_MIN_CMP(a, b)); +#else + PG_RETURN_INT32(pg_cmp_s16(a, b)); +#endif } static int @@ -93,7 +96,11 @@ btint2fastcmp(Datum x, Datum y, SortSupport ssup) int16 a = DatumGetInt16(x); int16 b = DatumGetInt16(y); - return (int) a - (int) b; +#ifdef STRESS_SORT_INT_MIN + return STRESS_SORT_INT_MIN_CMP(a, b); +#else + return pg_cmp_s16(a, b); +#endif } Datum @@ -111,12 +118,11 @@ btint4cmp(PG_FUNCTION_ARGS) int32 a = PG_GETARG_INT32(0); int32 b = PG_GETARG_INT32(1); - if (a > b) - PG_RETURN_INT32(A_GREATER_THAN_B); - else if (a == b) - PG_RETURN_INT32(0); - else - PG_RETURN_INT32(A_LESS_THAN_B); +#ifdef STRESS_SORT_INT_MIN + PG_RETURN_INT32(STRESS_SORT_INT_MIN_CMP(a, b)); +#else + PG_RETURN_INT32(pg_cmp_s32(a, b)); +#endif } Datum @@ -134,12 +140,11 @@ btint8cmp(PG_FUNCTION_ARGS) int64 a = PG_GETARG_INT64(0); int64 b = PG_GETARG_INT64(1); - if (a > b) - PG_RETURN_INT32(A_GREATER_THAN_B); - else if (a == b) - PG_RETURN_INT32(0); - else - PG_RETURN_INT32(A_LESS_THAN_B); +#ifdef STRESS_SORT_INT_MIN + PG_RETURN_INT32(STRESS_SORT_INT_MIN_CMP(a, b)); +#else + PG_RETURN_INT32(pg_cmp_s64(a, b)); +#endif } #if SIZEOF_DATUM < 8 @@ -149,12 +154,11 @@ btint8fastcmp(Datum x, Datum y, SortSupport ssup) int64 a = DatumGetInt64(x); int64 b = DatumGetInt64(y); - if (a > b) - return A_GREATER_THAN_B; - else if (a == b) - return 0; - else - return A_LESS_THAN_B; +#ifdef STRESS_SORT_INT_MIN + return STRESS_SORT_INT_MIN_CMP(a, b); +#else + return pg_cmp_s64(a, b); +#endif } #endif @@ -177,12 +181,11 @@ btint48cmp(PG_FUNCTION_ARGS) int32 a = PG_GETARG_INT32(0); int64 b = PG_GETARG_INT64(1); - if (a > b) - PG_RETURN_INT32(A_GREATER_THAN_B); - else if (a == b) - PG_RETURN_INT32(0); - else - PG_RETURN_INT32(A_LESS_THAN_B); +#ifdef STRESS_SORT_INT_MIN + PG_RETURN_INT32(STRESS_SORT_INT_MIN_CMP(a, b)); +#else + PG_RETURN_INT32(pg_cmp_s64(a, b)); +#endif } Datum @@ -191,12 +194,11 @@ btint84cmp(PG_FUNCTION_ARGS) int64 a = PG_GETARG_INT64(0); int32 b = PG_GETARG_INT32(1); - if (a > b) - PG_RETURN_INT32(A_GREATER_THAN_B); - else if (a == b) - PG_RETURN_INT32(0); - else - PG_RETURN_INT32(A_LESS_THAN_B); +#ifdef STRESS_SORT_INT_MIN + PG_RETURN_INT32(STRESS_SORT_INT_MIN_CMP(a, b)); +#else + PG_RETURN_INT32(pg_cmp_s64(a, b)); +#endif } Datum @@ -205,12 +207,11 @@ btint24cmp(PG_FUNCTION_ARGS) int16 a = PG_GETARG_INT16(0); int32 b = PG_GETARG_INT32(1); - if (a > b) - PG_RETURN_INT32(A_GREATER_THAN_B); - else if (a == b) - PG_RETURN_INT32(0); - else - PG_RETURN_INT32(A_LESS_THAN_B); +#ifdef STRESS_SORT_INT_MIN + PG_RETURN_INT32(STRESS_SORT_INT_MIN_CMP(a, b)); +#else + PG_RETURN_INT32(pg_cmp_s32(a, b)); +#endif } Datum @@ -219,12 +220,11 @@ btint42cmp(PG_FUNCTION_ARGS) int32 a = PG_GETARG_INT32(0); int16 b = PG_GETARG_INT16(1); - if (a > b) - PG_RETURN_INT32(A_GREATER_THAN_B); - else if (a == b) - PG_RETURN_INT32(0); - else - PG_RETURN_INT32(A_LESS_THAN_B); +#ifdef STRESS_SORT_INT_MIN + PG_RETURN_INT32(STRESS_SORT_INT_MIN_CMP(a, b)); +#else + PG_RETURN_INT32(pg_cmp_s32(a, b)); +#endif } Datum @@ -233,12 +233,11 @@ btint28cmp(PG_FUNCTION_ARGS) int16 a = PG_GETARG_INT16(0); int64 b = PG_GETARG_INT64(1); - if (a > b) - PG_RETURN_INT32(A_GREATER_THAN_B); - else if (a == b) - PG_RETURN_INT32(0); - else - PG_RETURN_INT32(A_LESS_THAN_B); +#ifdef STRESS_SORT_INT_MIN + PG_RETURN_INT32(STRESS_SORT_INT_MIN_CMP(a, b)); +#else + PG_RETURN_INT32(pg_cmp_s64(a, b)); +#endif } Datum @@ -247,12 +246,11 @@ btint82cmp(PG_FUNCTION_ARGS) int64 a = PG_GETARG_INT64(0); int16 b = PG_GETARG_INT16(1); - if (a > b) - PG_RETURN_INT32(A_GREATER_THAN_B); - else if (a == b) - PG_RETURN_INT32(0); - else - PG_RETURN_INT32(A_LESS_THAN_B); +#ifdef STRESS_SORT_INT_MIN + PG_RETURN_INT32(STRESS_SORT_INT_MIN_CMP(a, b)); +#else + PG_RETURN_INT32(pg_cmp_s64(a, b)); +#endif } Datum @@ -261,12 +259,11 @@ btoidcmp(PG_FUNCTION_ARGS) Oid a = PG_GETARG_OID(0); Oid b = PG_GETARG_OID(1); - if (a > b) - PG_RETURN_INT32(A_GREATER_THAN_B); - else if (a == b) - PG_RETURN_INT32(0); - else - PG_RETURN_INT32(A_LESS_THAN_B); +#ifdef STRESS_SORT_INT_MIN + PG_RETURN_INT32(STRESS_SORT_INT_MIN_CMP(a, b)); +#else + PG_RETURN_INT32(pg_cmp_u32(a, b)); +#endif } static int @@ -275,12 +272,11 @@ btoidfastcmp(Datum x, Datum y, SortSupport ssup) Oid a = DatumGetObjectId(x); Oid b = DatumGetObjectId(y); - if (a > b) - return A_GREATER_THAN_B; - else if (a == b) - return 0; - else - return A_LESS_THAN_B; +#ifdef STRESS_SORT_INT_MIN + return STRESS_SORT_INT_MIN_CMP(a, b); +#else + return pg_cmp_u32(a, b); +#endif } Datum @@ -305,12 +301,16 @@ btoidvectorcmp(PG_FUNCTION_ARGS) for (i = 0; i < a->dim1; i++) { - if (a->values[i] != b->values[i]) + Oid aval = a->values[i]; + Oid bval = b->values[i]; + + if (aval != bval) { - if (a->values[i] > b->values[i]) - PG_RETURN_INT32(A_GREATER_THAN_B); - else - PG_RETURN_INT32(A_LESS_THAN_B); +#ifdef STRESS_SORT_INT_MIN + PG_RETURN_INT32(STRESS_SORT_INT_MIN_CMP(aval, bval)); +#else + PG_RETURN_INT32(pg_cmp_u32(aval, bval)); +#endif } } PG_RETURN_INT32(0); diff --git a/src/backend/storage/page/itemptr.c b/src/backend/storage/page/itemptr.c index af21170307..d85592951e 100644 --- a/src/backend/storage/page/itemptr.c +++ b/src/backend/storage/page/itemptr.c @@ -14,6 +14,7 @@ */ #include "postgres.h" +#include "common/int.h" #include "storage/itemptr.h" @@ -57,18 +58,11 @@ ItemPointerCompare(ItemPointer arg1, ItemPointer arg2) BlockNumber b1 = ItemPointerGetBlockNumberNoCheck(arg1); BlockNumber b2 = ItemPointerGetBlockNumberNoCheck(arg2); - if (b1 < b2) - return -1; - else if (b1 > b2) - return 1; - else if (ItemPointerGetOffsetNumberNoCheck(arg1) < - ItemPointerGetOffsetNumberNoCheck(arg2)) - return -1; - else if (ItemPointerGetOffsetNumberNoCheck(arg1) > - ItemPointerGetOffsetNumberNoCheck(arg2)) - return 1; - else - return 0; + if (b1 != b2) + return pg_cmp_u32(b1, b2); + + return pg_cmp_u16(ItemPointerGetOffsetNumberNoCheck(arg1), + ItemPointerGetOffsetNumberNoCheck(arg2)); } /* diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c index c960cfa823..ec1ff3e656 100644 --- a/src/backend/utils/sort/tuplesort.c +++ b/src/backend/utils/sort/tuplesort.c @@ -102,6 +102,7 @@ #include #include "commands/tablespace.h" +#include "common/int.h" #include "miscadmin.h" #include "pg_trace.h" #include "storage/shmem.h" @@ -3138,12 +3139,18 @@ free_sort_tuple(Tuplesortstate *state, SortTuple *stup) int ssup_datum_unsigned_cmp(Datum x, Datum y, SortSupport ssup) { +#if SIZEOF_DATUM == 4 + return pg_cmp_u32(x, y); +#elif SIZEOF_DATUM == 8 + return pg_cmp_u64(x, y); +#else if (x < y) return -1; else if (x > y) return 1; else return 0; +#endif } #if SIZEOF_DATUM >= 8 @@ -3153,12 +3160,7 @@ ssup_datum_signed_cmp(Datum x, Datum y, SortSupport ssup) int64 xx = DatumGetInt64(x); int64 yy = DatumGetInt64(y); - if (xx < yy) - return -1; - else if (xx > yy) - return 1; - else - return 0; + return pg_cmp_s64(xx, yy); } #endif @@ -3168,10 +3170,5 @@ ssup_datum_int32_cmp(Datum x, Datum y, SortSupport ssup) int32 xx = DatumGetInt32(x); int32 yy = DatumGetInt32(y); - if (xx < yy) - return -1; - else if (xx > yy) - return 1; - else - return 0; + return pg_cmp_s32(xx, yy); } -- 2.39.5 (Apple Git-154) --STuNuYHiUS+fxQmC--