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 1the5T-0058vX-K1 for pgsql-hackers@arkaria.postgresql.org; Tue, 11 Feb 2025 00:25:16 +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 1the5R-0061mh-7C for pgsql-hackers@arkaria.postgresql.org; Tue, 11 Feb 2025 00:25:13 +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 1the5Q-0061k0-0O for pgsql-hackers@lists.postgresql.org; Tue, 11 Feb 2025 00:25:12 +0000 Received: from mgamail.intel.com ([198.175.65.21]) by makus.postgresql.org with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1the5L-0007d5-2F for pgsql-hackers@lists.postgresql.org; Tue, 11 Feb 2025 00:25:10 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1739233507; x=1770769507; h=from:to:cc:subject:date:message-id:references: in-reply-to:mime-version; bh=U5F2rZUD5rWbKfoQGoyslXC8wBImwjkUoSC3jyUpM+E=; b=EHXkaFLQPkADyE8jmzwkzuoclcKwbAgH+6Q2lSWkjGB/QT0fuYMfrEaO Y8DDN1sKDRm9E9eUGzRLAQw9cTUSFwzMJomCx2ICSpeGuKKXQHjBHSzl+ 26TKyBfO01bLT1CF62lOaYbFmoYp+4nBPNHEYomDgYStlNUSMyz95ZW44 aD9e6KYyzAPRzQWo6tSSdfWvWBiqf3NmKBMyTwLWnxjCXOta1FnTKs2Q6 aoVPOgVvHNP+i1xumIxJi207NbI7rOugsTkeniQBK2fpzgY49cmONYoF+ ZNqc1NpnuTJKVr2c6zT3NHA5S1V1kPZqsA/wHRLMyvkLVjIliRruN2nMh A==; X-CSE-ConnectionGUID: 9d6dZ65tTz+8iRRS7H+WSQ== X-CSE-MsgGUID: I+4lcvp1TJKff4K+26hmtQ== X-IronPort-AV: E=McAfee;i="6700,10204,11341"; a="39752897" X-IronPort-AV: E=Sophos;i="6.13,275,1732608000"; d="scan'208,217";a="39752897" Received: from orviesa005.jf.intel.com ([10.64.159.145]) by orvoesa113.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Feb 2025 16:25:03 -0800 X-CSE-ConnectionGUID: Sf6Tx5mbQiW0oKR5fBl4rQ== X-CSE-MsgGUID: cCcMMwlETWWzFRVSgrewow== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208,217";a="117551325" Received: from orsmsx603.amr.corp.intel.com ([10.22.229.16]) by orviesa005.jf.intel.com with ESMTP/TLS/AES256-GCM-SHA384; 10 Feb 2025 16:25:04 -0800 Received: from orsmsx601.amr.corp.intel.com (10.22.229.14) by ORSMSX603.amr.corp.intel.com (10.22.229.16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.44; Mon, 10 Feb 2025 16:25:02 -0800 Received: from orsedg603.ED.cps.intel.com (10.7.248.4) by orsmsx601.amr.corp.intel.com (10.22.229.14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.44 via Frontend Transport; Mon, 10 Feb 2025 16:25:02 -0800 Received: from NAM12-BN8-obe.outbound.protection.outlook.com (104.47.55.172) by edgegateway.intel.com (134.134.137.100) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.44; Mon, 10 Feb 2025 16:25:01 -0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=K60tCZcQYUCT0W+PSB374z4VlUZcTNE1ppAi4og+iUpBA9hbEiVfyqJivJ8jOgbYphC2b9CKIdZbhWVxmkCiLoTymOOy3gk9UfK3j+OH4t0LtDccujtSwUjtVu/0CHmMwGX1rvaEKsQoUyCUd78SuA2JW5+U/nTDME/VkxXmXOLB6cgmrz2ocuY8781Y4jjBPBcG0WApsJo9j8lgYSKgVjf7pgJDJ4J5xjeI3tj/VjdlAJ00wLWbxu5Uk9RFPaapLJuIGfdigqtJO2n6T5fqXXc/IAVJEARAO20BP9GbxFcDaQh/hAe5y94GYveGIiIQevHYkTnxr6K+920WQ2fihA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=4c0kda3XDCBMKD6/QQ3kBTiiljCExGuRV5uZ21QHPJk=; b=keFrX5K0v6iMjhRq/SsRHS7HOzgjxXHG4XZg6B15RBAcP97L+EoyKHn4Gxr9R+oieYYvia9lT5j6Pgd8bk4FDvfA9W2iZ5i504TnM8BVpXg2VJRDjSfh6bMgVm217lZ0uCN+TaG5q5BiZvWTn+FTCuz9ep6vHcxxIE2w5u+6wS0mj5N/JYwOSgCr4i64e/a9mw5qCZZaxK3jbEq6cupVepBkXBYXDdJCHdm/5yu6+yBjzy10eiZLO2Y5sSxDihH4TalRbC1WIzxNEq0kfab8dCZVjBsWkp9WN/qg96kcBh6a1sALRGTJ6MUnfXosJSfsPMxkeOcZ0iTHYX5twAM/uQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none Received: from PH8PR11MB8286.namprd11.prod.outlook.com (2603:10b6:510:1c6::15) by SN7PR11MB7491.namprd11.prod.outlook.com (2603:10b6:806:349::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8422.18; Tue, 11 Feb 2025 00:24:45 +0000 Received: from PH8PR11MB8286.namprd11.prod.outlook.com ([fe80::f7a1:1fa0:66e5:d03f]) by PH8PR11MB8286.namprd11.prod.outlook.com ([fe80::f7a1:1fa0:66e5:d03f%4]) with mapi id 15.20.8422.012; Tue, 11 Feb 2025 00:24:45 +0000 From: "Devulapalli, Raghuveer" To: "pgsql-hackers@lists.postgresql.org" , John Naylor CC: "Shankaran, Akash" , "Devulapalli, Raghuveer" Subject: RE: Improve CRC32C performance on SSE4.2 Thread-Topic: Improve CRC32C performance on SSE4.2 Thread-Index: Adt4DVguiQIdIdAlTHKdderyKKLizwEBOgDg Date: Tue, 11 Feb 2025 00:24:45 +0000 Message-ID: References: In-Reply-To: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=intel.com; x-ms-publictraffictype: Email x-ms-traffictypediagnostic: PH8PR11MB8286:EE_|SN7PR11MB7491:EE_ x-ms-office365-filtering-correlation-id: ee0d1b54-e5cd-4ff9-32e2-08dd4a327c96 x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0;ARA:13230040|1800799024|376014|366016|8096899003|13003099007|38070700018; x-microsoft-antispam-message-info: =?us-ascii?Q?TH/hxPjtC/PfRFJmlBmjSVZKfVDlBHWYrA4nvKDL+rklRz4kJxba7O6QVbKj?= =?us-ascii?Q?AKoeyMZVPW0665IhgvTxWtFwzN54dAOPzMAP1edwkpOWdiBiL4agi8SEOEjs?= =?us-ascii?Q?vUTpcNLNUUmjTsxsvhvrMZv09KkbQTRIv3CtKLlrlNBE/7fPNxKit7Ay2N3W?= =?us-ascii?Q?99konzsLzjo04lP4y8etBAp8+PkE2h4qYNNwfLBfMGDAuT8pMlAyEpWwy1X1?= =?us-ascii?Q?igCgTLnRNAvqk8vWkrhv/JoU8IYpuiPXVAuZKGMG27Z7PdFs1vRuPNrSpAQ4?= =?us-ascii?Q?kwt+dIN2n8EiYQUfQFI4M/bKLOEi2ShHhliQpsk7c2WulJ46mVEZCSTIxuDX?= =?us-ascii?Q?0IJYnaBN1mvbEIO7H+1yDKPZhjoIbPW7gN3L/ugguTmiEqqsDuZa2JzMs7Cu?= =?us-ascii?Q?Q8a67VriKso9lffXjplM356Ze94HZ4ZLygPH1ETDX9GyDRP5xZBFh6TvEG1c?= =?us-ascii?Q?GbNNT1HouGa7aXvnu01D9gAS6AEntHndED3aA/1lvFKtSV2IAioZ6ZpOd2Gi?= =?us-ascii?Q?4TMhNVwmX8jRmp9EyGVNqmq1Ok4R2FMDfQMfPtGNhEpUWFQzLe+VXVMRlVdP?= =?us-ascii?Q?rQ09VFR+hK1xHcQz3yBieS8UsmdkL3MeqoBCJTqwcyysrB4IBa60+LtBRB4a?= =?us-ascii?Q?Dbanu7JZz241xZMIJ8nx18IreJSmNvdIpT0bX1yvbQiS6ve+tr6BPxmFahrV?= =?us-ascii?Q?/OxqUjD11QQzedgjL4v6ArHts1wl3S+9Me9GFK+JbxNW6WcntBLDFTK0RvIQ?= =?us-ascii?Q?NPhi0Zy3JeEa8A2UI0RpqW6oLpnYmZilzkrTEwHf3I0ML28CWBQ8FfbDcAZt?= =?us-ascii?Q?GohdejVPhXWUs6L6IgKGSs6taPo78PnpItN5uKKejJIz8oYxZWionAg+QU3I?= =?us-ascii?Q?l9PufkE1mr1nyZZNTLprMT2igfpq32V5g51bpdFe3dtaTI+B5NO/kJynJ/j9?= =?us-ascii?Q?kmiITxKSonUWlA60qKcNOfuzDN9pSZVW4sC1AMyorlqfzdrMzML9gJ0qqGrD?= =?us-ascii?Q?KuQFFkMoQiYjwNuL69QERp69LyATEoiT3Z3bcXYuRYApewf0i8GKM/+OiTyT?= =?us-ascii?Q?UeIdJL2kKAbc///b63EmyjSXo9d0VzXQ0FkEJ+rW0XsKijFRfWTcxvbWiJ6v?= =?us-ascii?Q?uNNpld+R7F1I1Tc8BNUzUKWc7zhgWqvO0bT7qDHy6pI2wCPqX6h4npS5BK6s?= =?us-ascii?Q?OkGKcXBTGEIlGHg3k9Q+7HYwLZlj0Be8W3iLp16ksx7GD7jDm+Z9+2J8q/WB?= =?us-ascii?Q?2QvjB5l27fecSWEXAhWDPTgwCugcvVrtop1thmDmCHOqCgnCrs3SBHreCsAZ?= =?us-ascii?Q?URROa1eyjmsmMpBZPF27sMDpENc9l8Ph54Rduv2SdoimridCT/vNc/F17i+L?= =?us-ascii?Q?eaDTMImUmpDAlaKRoPimYwJKovxb/Z3PaJEVOkFuALq5yacZxw=3D=3D?= x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PH8PR11MB8286.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(1800799024)(376014)(366016)(8096899003)(13003099007)(38070700018);DIR:OUT;SFP:1101; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?nQqvvv4sByIGM8TQ9DtNLnbPdfL+Sjfp2H1xuc8i6Sq7umshpKANOWckN8Nh?= =?us-ascii?Q?4UZwpsCwM7NdWP/Dg16ze30VoqWAUnGIxYfMEYlf7huurg4B615oWMZzOxYL?= =?us-ascii?Q?AsCkkXal6QRthTY7zDcrHLHN+4y/jFrkHSd/XVLkUaUbbmLc60dUE32YTrpm?= =?us-ascii?Q?h2HaRvmsUrzyuPcAmWa2hI99FMYM2XGiLRLf2NgjbNaOLnIdXNkg67bRJwm6?= =?us-ascii?Q?BBqb2XJCbMao0MhUooQvsqLeGUZ8iWWJNR+weJtqU3CC3TQdR77MGwaGQvCg?= =?us-ascii?Q?Vs4afnODm8nniMbcXeeVU1ISHmpaWL2gqEFlMy58Zxq4fYX7TrPcs+2SkMb1?= =?us-ascii?Q?lS+4BTyJsmowVm+VtzjCw8yzSoTw8mcnEYV3bhyI6fXL3/4rK5ED9KDWYwKg?= =?us-ascii?Q?1iB7ZKrpU+EAzjFPRz8u3PCnahf8sZ9zcUfu27+1DJUqYtsBrqEt0hx+xfuJ?= =?us-ascii?Q?UJ5dJnpS9NW4hWXOAAKEqm1JfOUYC3YwRF9QtgzLW43yeY2IzVhD9CexCsFg?= =?us-ascii?Q?lxJOlZM82mmXZGgWl8ID9hVup880ThWkn5uZ7ZnmS2o1LZuljvDFK0StZS2r?= =?us-ascii?Q?Xz1A6DQf3sbvp5llimkFhF9ZyI8riNuAnlHqLF8vPNYBBTh5xh6IgHC67XYa?= =?us-ascii?Q?we+D8Zh3s2FTyFWg6fpcCH7OcmdqAlvCZNiA9JXh/Te6zn23pb0ufW43FmVY?= =?us-ascii?Q?pyIEdCfQaPVV+4eyDxBf/AkQpDTZgpLOnZW8pDfBI2gBw1cotjN5Yvwckju5?= =?us-ascii?Q?lrEJuHWjUpipzOPism8JdA4IhSnbzSY+uk4A3Gzf+ccvt7hj+nS6qwpJXczK?= =?us-ascii?Q?23U//W9Sp3ulWAd+EEzAuJ+xaWnlwkRUZc8pwazbPizkH8ramrE/P1pkJmcw?= =?us-ascii?Q?KV7aiMKgxdyPBpxlDZ3JrnanPSz9qrI5EBlD8D68LRAHVhw6T6YiPC3gQEho?= =?us-ascii?Q?Jg/JJHG0e1UrjfMbua0vXfJUihqGLXjVwO4YvBktPEp0oDIw5v5PP7krp4dg?= =?us-ascii?Q?C+pzu4/6GIhLMdUj64PSUGnRa8SjAUWhy7/YgC9Ah97JGiFHfS00LkSTXqD8?= =?us-ascii?Q?5VfOoblmCRh3AeLgU7JwXh9waIWSRv2w3KWeSxWQN3DtfpBeh7yUU+Mb2L+Q?= =?us-ascii?Q?lrrYzqVCBCQAEYvdEDWe181nmTtzoU/Ao6hGAsLCubbIZ4QQX7/G9uzWOtpk?= =?us-ascii?Q?A78Ct5QvhqZ1tz4w8saJidMYR8DRRORMyeSsZyOdT3CrUD13et3xj4crmLnJ?= =?us-ascii?Q?0up70ntrnrJS2sAEDVlU2v/xWCAC3LOPzkgzCSpufAItonivZZo1p5sFtvum?= =?us-ascii?Q?vJSxUn0Wlrlnq3K9xvLGu5Xz4veRSqOyGD5tZ22AP+ooCX+Mr6yDmzKGEvV4?= =?us-ascii?Q?HchAAqQq9yr0PaQ5gsDlJvW40cigHkmY2FICZbvHvDA9i95iKMU5zCnhOz7L?= =?us-ascii?Q?ZsQJfPfhwN9NKm2VpY8E3HlbLPDyH+KuEbVwjCDwkxMCQl9MAu3ex2yHF3D3?= =?us-ascii?Q?R2aS2GuhtS0jOvP+E+xD9lm3gpQr0C4DvLsygAnJntdTv5MgrtLmpwsWzpQr?= =?us-ascii?Q?q7UhGZ+yMEAJ8ulUO8AT9DimPWh1Pe1srA8x0G2W1i9qLu9DH5zdDXRt+IH4?= =?us-ascii?Q?+g=3D=3D?= Content-Type: multipart/alternative; boundary="_000_PH8PR11MB8286F844321BA1DEEC518348FBFD2PH8PR11MB8286namp_" MIME-Version: 1.0 X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: PH8PR11MB8286.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: ee0d1b54-e5cd-4ff9-32e2-08dd4a327c96 X-MS-Exchange-CrossTenant-originalarrivaltime: 11 Feb 2025 00:24:45.5282 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: E43FfrR5Gj6I/opUAMNT1rpZZ96pG7LhSHIv7ueA690Njxsx0b+1x/to8Cc0865tbEJ03YZhiO9Sji39s1xQuQadY8+SnCPhuZWt227h7Xg= X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN7PR11MB7491 X-OriginatorOrg: intel.com List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --_000_PH8PR11MB8286F844321BA1DEEC518348FBFD2PH8PR11MB8286namp_ Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Hi John, > I'm highly suspicious of these numbers because they show this version > is about 20x faster than "scalar", so relatively speaking 3x faster > than the AVX-512 proposal? Apologies for this. I was suspicious of this too and looks like I had unint= entionally set the scalar version I wrote for testing CRC32C correctness (= which computes crc one byte at time). The code for microbenchmarking is all= here: https://github.com/r-devulap/crc32c and this commit https://github.c= om/r-devulap/crc32c/commit/ca4d1b24fd8af87aab544fb1634523b6657325a0 fixes t= hat. Rerunning the benchmarks gives me more sensible numbers: Comparing scalar_crc32c to sse42_crc32c (from ./bench) Benchmark Time CP= U Time Old Time New CPU Old CPU New ---------------------------------------------------------------------------= --------------------------------------------------------- [scalar_crc32c vs. sse42_crc32c]/64 -0.0972 -0.097= 1 5 4 5 4 [scalar_crc32c vs. sse42_crc32c]/128 -0.3048 -0.304= 8 8 6 8 6 [scalar_crc32c vs. sse42_crc32c]/256 -0.4610 -0.461= 0 19 10 19 10 [scalar_crc32c vs. sse42_crc32c]/512 -0.6432 -0.643= 2 50 18 50 18 [scalar_crc32c vs. sse42_crc32c]/1024 -0.7192 -0.719= 2 121 34 121 34 [scalar_crc32c vs. sse42_crc32c]/2048 -0.7275 -0.727= 6 259 70 259 70 > Luckily, that's easily fixable: It turns out the implementation > in the paper (and chromium) has a very inefficient finalization step, > using more carryless multiplications and plenty of other operations. > After the main loop, and at the end, it's much more efficient to > convert the 128-bit intermediate result directly into a CRC in the > usual way. Thank you for pointing this out and also fixing it! This improves over the = chromium version by 10-25% especially for with smaller byte size 64 - 512 b= ytes: Comparing sse42_crc32c to corsix_crc32c (from ./bench) Benchmark Time CP= U Time Old Time New CPU Old CPU New ---------------------------------------------------------------------------= --------------------------------------------------------- [sse42_crc32c vs. corsix_crc32c]/64 -0.2696 -0.269= 6 4 3 4 3 [sse42_crc32c vs. corsix_crc32c]/128 -0.1551 -0.155= 2 6 5 6 5 [sse42_crc32c vs. corsix_crc32c]/256 -0.1787 -0.178= 7 10 8 10 8 [sse42_crc32c vs. corsix_crc32c]/512 -0.1351 -0.135= 1 18 15 18 15 [sse42_crc32c vs. corsix_crc32c]/1024 -0.0972 -0.097= 2 34 31 34 31 [sse42_crc32c vs. corsix_crc32c]/2048 -0.0763 -0.076= 3 69 64 69 64 OVERALL_GEOMEAN -0.1544 -0.154= 4 0 0 0 0 > I generated a similar function for v2-0004 and this benchmark shows it's = faster than master on 128 bytes and above. I ran the same benchmark drive_crc32c with the postgres infrastructure and = found that your v2 sse42 version from corsix is slower than pg_comp_crc32c_= sse42 in master branch when buffer is < 128 bytes. I think the reason is th= at postgres is not using -O3 flag build the crc32c source files and the com= piler generates less than optimal code. Adding that flag fixes the regressi= on for buffers with 64 bytes - 128 bytes. Could you confirm that behavior o= n your end too? --- src/port/pg_crc32c_sse42.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/port/pg_crc32c_sse42.c b/src/port/pg_crc32c_sse42.c index a8c1e5609b..a350b1b93a 100644 --- a/src/port/pg_crc32c_sse42.c +++ b/src/port/pg_crc32c_sse42.c @@ -81,6 +81,7 @@ pg_comp_crc32c_sse42_tail(pg_crc32c crc, const void *data= , size_t len) #define clmul_lo(a, b) (_mm_clmulepi64_si128((a), (b), 0)) #define clmul_hi(a, b) (_mm_clmulepi64_si128((a), (b), 17)) pg_attribute_no_sanitize_alignment() +__attribute__((optimize("-O3"))) pg_attribute_target("sse4.2,pclmul") pg_crc32c pg_comp_crc32c_sse42(pg_crc32c crc0, const void *data, size_t len) -- You could also just build with export CFLAGS=3D"-O3" instead of adding the = function attribute. > I did the benchmarks on my older machine, which I believe has a latency o= f 7 cycles for this instruction. May I ask which processor does you older machine have? I am benchmarking on= a Tigerlake processor. > It's probably okay to fold these together in the same compile-time > check, since both are fairly old by now, but for those following > along, pclmul is not in SSE 4.2 and is a bit newer. So this would > cause machines building on Nehalem (2008) to fail the check and go > back to slicing-by-8 with it written this way. Technically, the current version of the patch does not have a runtime cpuid= check for pclmul and so would cause it to crash with segill on Nehalam (cu= rrently we only check for sse4.2). This needs to be fixed by adding an addi= tional cpuid check for pcmul but it would fall back to slicing by 8 on Neha= lem and use the latest version on Westmere and above. If you care about kee= ping the performance on Nehalem, then I am happy to update the choose funct= ion to pick the right pointer accordingly. Let me know which one you would= prefer. Raghuveer From: Devulapalli, Raghuveer Sent: Wednesday, February 5, 2025 12:49 PM To: pgsql-hackers@lists.postgresql.org Cc: Shankaran, Akash ; Devulapalli, Raghuveer Subject: Improve CRC32C performance on SSE4.2 This patch improves the performance of SSE42 CRC32C algorithm. The current = SSE4.2 implementation of CRC32C relies on the native crc32 instruction and = processes 8 bytes at a time in a loop. The technique in this paper uses th= e pclmulqdq instruction and processing 64 bytes at time. The algorithm is b= ased on sse42 version of crc32 computation from Chromium's copy of zlib wit= h modified constants for crc32c computation. See: https://chromium.googlesource.com/chromium/src/+/refs/heads/main/third_part= y/zlib/crc32_simd.c Microbenchmarks (generated with google benchmark using a standalone version= of the same algorithms): Comparing scalar_crc32c to sse42_crc32c (for various buffer sizes: 64, 128,= 256, 512, 1024, 2048 bytes) Benchmark Time CP= U Time Old Time New CPU Old CPU New ---------------------------------------------------------------------------= --------------------------------------------------------- [scalar_crc32c vs. sse42_crc32c]/64 -0.8147 -0.814= 8 33 6 33 6 [scalar_crc32c vs. sse42_crc32c]/128 -0.8962 -0.8962= 88 9 88 9 [scalar_crc32c vs. sse42_crc32c]/256 -0.9200 -0.9200= 211 17 211 17 [scalar_crc32c vs. sse42_crc32c]/512 -0.9389 -0.9389= 486 30 486 30 [scalar_crc32c vs. sse42_crc32c]/1024 -0.9452 -0.9452 = 1037 57 1037 57 [scalar_crc32c vs. sse42_crc32c]/2048 -0.9456 -0.9456 = 2140 116 2140 116 Raghuveer --_000_PH8PR11MB8286F844321BA1DEEC518348FBFD2PH8PR11MB8286namp_ Content-Type: text/html; charset="us-ascii" Content-Transfer-Encoding: quoted-printable

Hi John,

 

> I'm highly suspicious of these numbers because = they show this version

> is about 20x faster than "scalar", so= relatively speaking 3x faster

> than the AVX-512 proposal?

 

Apologies for this. I was suspicious of this too and= looks like I had unintentionally set the scalar version I wrote  for = testing CRC32C correctness (which computes crc one byte at time). The code = for microbenchmarking is all here: https://github.com/r-devula= p/crc32c and this commit https://github.com/r-devulap/crc32c/commit/ca4d1b24fd8af87aab544fb1634523b6= 657325a0 fixes that. Rerunning the benchmarks gives me more sensible nu= mbers:

 

Comparing scalar_crc32c to sse42_crc32c (from ./benc= h)

Benchmark       &= nbsp;           &nbs= p;            &= nbsp;           &nbs= p;  Time          &n= bsp;  CPU      Time Old   &nbs= p;  Time New       CPU Old  &n= bsp;    CPU New

----------------------------------------------------= ---------------------------------------------------------------------------= -----

[scalar_crc32c vs. sse42_crc32c]/64   = ;            &n= bsp;  -0.0972         -0.0971&= nbsp;            5&n= bsp;            4&nb= sp;            5&nbs= p;            4=

[scalar_crc32c vs. sse42_crc32c]/128  &nbs= p;            &= nbsp; -0.3048         -0.3048 =             8 &= nbsp;           6 &n= bsp;           8 &nb= sp;           6

[scalar_crc32c vs. sse42_crc32c]/256  &nbs= p;            &= nbsp; -0.4610         -0.4610 =            19  =           10   =          19    =         10

[scalar_crc32c vs. sse42_crc32c]/512  &nbs= p;            &= nbsp; -0.6432         -0.6432 =            50  =           18   =          50    =         18

[scalar_crc32c vs. sse42_crc32c]/1024  &nb= sp;            = -0.7192         -0.7192  = ;         121   &nbs= p;        34    &nbs= p;      121      &nb= sp;     34

[scalar_crc32c vs. sse42_crc32c]/2048  &nb= sp;            = -0.7275         -0.7276  = ;         259   &nbs= p;        70    &nbs= p;      259      &nb= sp;     70

 

> Luckily, that's easily fixable: It turns out th= e implementation

> in the paper (and chromium) has a very ineffici= ent finalization step,

>  using more carryless multiplications and = plenty of other operations.

> After the main loop, and at the end, it's much = more efficient to

> convert the 128-bit intermediate result directl= y into a CRC in the

> usual way.

 

Thank you for pointing this out and also fixing it! = This improves over the chromium version by 10-25% especially for with small= er byte size 64 – 512 bytes:

 

Comparing sse42_crc32c to corsix_crc32c (from ./benc= h)

Benchmark       &= nbsp;           &nbs= p;            &= nbsp;           &nbs= p;  Time          &n= bsp;  CPU      Time Old   &nbs= p;  Time New       CPU Old  &n= bsp;    CPU New

----------------------------------------------------= ---------------------------------------------------------------------------= -----

[sse42_crc32c vs. corsix_crc32c]/64   = ;            &n= bsp;  -0.2696         -0.2696&= nbsp;            4&n= bsp;            3&nb= sp;            4&nbs= p;            3=

[sse42_crc32c vs. corsix_crc32c]/128  &nbs= p;            &= nbsp; -0.1551         -0.1552 =             6 &= nbsp;           5 &n= bsp;           6 &nb= sp;           5

[sse42_crc32c vs. corsix_crc32c]/256  &nbs= p;            &= nbsp; -0.1787         -0.1787 =            10  =            8  &= nbsp;         10   &= nbsp;         8

[sse42_crc32c vs. corsix_crc32c]/512  &nbs= p;            &= nbsp; -0.1351         -0.1351 =            18  =           15   =          18    =         15

[sse42_crc32c vs. corsix_crc32c]/1024  &nb= sp;            = -0.0972         -0.0972  = ;          34   = ;         31    = ;        34     = ;       31

[sse42_crc32c vs. corsix_crc32c]/2048  &nb= sp;            = -0.0763         -0.0763  = ;          69   = ;         64    = ;        69     = ;       64

OVERALL_GEOMEAN      &= nbsp;           &nbs= p;            &= nbsp;      -0.1544     &n= bsp;   -0.1544        &nb= sp;    0        &nbs= p;    0         = ;    0         =     0

 

> I generated a similar function for v2-0004 and = this benchmark shows it's faster than master on 128 bytes and above.

 

I ran the same benchmark drive_crc32c with the postg= res infrastructure and found that your v2 sse42 version from corsix is slow= er than pg_comp_crc32c_sse42 in master branch when buffer is < 128 bytes= . I think the reason is that postgres is not using -O3 flag build the crc32c source files and the compiler gener= ates less than optimal code. Adding that flag fixes the regression for buff= ers with 64 bytes – 128 bytes. Could you confirm that behavior on you= r end too?

 

---

src/port/pg_crc32c_sse42.c | 1 +

1 file changed, 1 insertion(+)

 

diff --git a/src/port/pg_crc32c_sse42.c b/src/port/p= g_crc32c_sse42.c

index a8c1e5609b..a350b1b93a 100644

--- a/src/port/pg_crc32c_sse42.c

+++ b/src/port/pg_crc32c_sse42.c

@@ -81,6 +81,7 @@ pg_comp_crc32c_sse42_tail(pg_crc32= c crc, const void *data, size_t len)

#define clmul_lo(a, b) (_mm_clmulepi64_si128((a), (b= ), 0))

#define clmul_hi(a, b) (_mm_clmulepi64_si128((a), (b= ), 17))

pg_attribute_no_sanitize_alignment()

+__attribute__((optimize("-O3")))

pg_attribute_target("sse4.2,pclmul")<= /o:p>

pg_crc32c

pg_comp_crc32c_sse42(pg_crc32c crc0, const void *dat= a, size_t len)

--

 

You could also just build with export CFLAGS=3D"= ;-O3" instead of adding the function attribute.

 

> I did the benchmarks on my older machine, which= I believe has a latency of 7 cycles for this instruction.

 

May I ask which processor does you older machine hav= e? I am benchmarking on a Tigerlake processor.

 

> It's probably okay to fold these together in th= e same compile-time

> check, since both are fairly old by now, but fo= r those following

> along, pclmul is not in SSE 4.2 and is a bit ne= wer. So this would

> cause machines building on Nehalem (2008) to fa= il the check and go

> back to slicing-by-8 with it written this way.<= o:p>

 

Technically, the current version of the patch does n= ot have a runtime cpuid check for pclmul and so would cause it to crash wit= h segill on Nehalam (currently we only check for sse4.2). This needs to be = fixed by adding an additional cpuid check for pcmul but it would fall back to slicing by 8 on Nehalem and use = the latest version on Westmere and above. If you care about keeping the per= formance on Nehalem, then I am happy to update the choose function to pick = the right pointer accordingly.  Let me know which one you would prefer.

 

Raghuveer

 

From: Devulapalli, Raghuveer <= ;raghuveer.devulapalli@intel.com>
Sent: Wednesday, February 5, 2025 12:49 PM
To: pgsql-hackers@lists.postgresql.org
Cc: Shankaran, Akash <akash.shankaran@intel.com>; Devulapalli,= Raghuveer <raghuveer.devulapalli@intel.com>
Subject: Improve CRC32C performance on SSE4.2

 

This patch improves the performance of SSE42 CRC32C = algorithm. The current SSE4.2 implementation of CRC32C relies on the native= crc32 instruction and processes 8 bytes at a time in a loop. The technique= in  this paper uses the pclmulqdq instruction and processing 64 bytes at time. The algorithm is based on sse= 42 version of crc32 computation from Chromium’s copy of zlib with mod= ified constants for crc32c computation. See:

 

https://chromium.goo= glesource.com/chromium/src/+/refs/heads/main/third_party/zlib/crc32_simd.c<= /a>

 

Microbenchmarks (generated with google benchmark usi= ng a standalone version of the same algorithms):

 

Comparing scalar_crc32c to sse42_crc32c (for various= buffer sizes: 64, 128, 256, 512, 1024, 2048 bytes)

Benchmark       &= nbsp;           &nbs= p;            &= nbsp;           &nbs= p;  Time          &n= bsp;  CPU      Time Old   &nbs= p;  Time New       CPU Old  &n= bsp;    CPU New

----------------------------------------------------= ---------------------------------------------------------------------------= -----

[scalar_crc32c vs. sse42_crc32c]/64   = ;            &n= bsp;  -0.8147         -0.8148&= nbsp;           33 &= nbsp;           6 &n= bsp;          33  &n= bsp;          6

[scalar_crc32c vs. sse42_crc32c]/128  &nbs= p;             = -0.8962         -0.8962  =           88   =           9   &= nbsp;        88    &= nbsp;        9

[scalar_crc32c vs. sse42_crc32c]/256  &nbs= p;             = -0.9200         -0.9200  =          211    = ;        17     = ;      211      &nbs= p;     17

[scalar_crc32c vs. sse42_crc32c]/512  &nbs= p;             = -0.9389         -0.9389  =          486    = ;        30     = ;      486      &nbs= p;     30

[scalar_crc32c vs. sse42_crc32c]/1024  &nb= sp;           -0.9452&nbs= p;        -0.9452    = ;      1037      &nb= sp;     57       &nb= sp;  1037          &= nbsp; 57

[scalar_crc32c vs. sse42_crc32c]/2048   &n= bsp;         -0.9456 &nbs= p;       -0.9456     = ;     2140       &nb= sp;   116          2= 140           116

 

Raghuveer

--_000_PH8PR11MB8286F844321BA1DEEC518348FBFD2PH8PR11MB8286namp_--