Line data Source code
1 : /*------------------------------------------------------------------------- 2 : * 3 : * pg_crc32c_sse42.c 4 : * Compute CRC-32C checksum using Intel SSE 4.2 instructions. 5 : * 6 : * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group 7 : * Portions Copyright (c) 1994, Regents of the University of California 8 : * 9 : * 10 : * IDENTIFICATION 11 : * src/port/pg_crc32c_sse42.c 12 : * 13 : *------------------------------------------------------------------------- 14 : */ 15 : #include "c.h" 16 : 17 : #include <nmmintrin.h> 18 : 19 : #include "port/pg_crc32c.h" 20 : 21 : pg_attribute_no_sanitize_alignment() 22 : pg_attribute_target("sse4.2") 23 : pg_crc32c 24 156737904 : pg_comp_crc32c_sse42(pg_crc32c crc, const void *data, size_t len) 25 : { 26 156737904 : const unsigned char *p = data; 27 156737904 : const unsigned char *pend = p + len; 28 : 29 : /* 30 : * Process eight bytes of data at a time. 31 : * 32 : * NB: We do unaligned accesses here. The Intel architecture allows that, 33 : * and performance testing didn't show any performance gain from aligning 34 : * the begin address. 35 : */ 36 : #ifdef __x86_64__ 37 7548847390 : while (p + 8 <= pend) 38 : { 39 7392109486 : crc = (uint32) _mm_crc32_u64(crc, *((const uint64 *) p)); 40 7392109486 : p += 8; 41 : } 42 : 43 : /* Process remaining full four bytes if any */ 44 156737904 : if (p + 4 <= pend) 45 : { 46 93787204 : crc = _mm_crc32_u32(crc, *((const unsigned int *) p)); 47 93787204 : p += 4; 48 : } 49 : #else 50 : 51 : /* 52 : * Process four bytes at a time. (The eight byte instruction is not 53 : * available on the 32-bit x86 architecture). 54 : */ 55 : while (p + 4 <= pend) 56 : { 57 : crc = _mm_crc32_u32(crc, *((const unsigned int *) p)); 58 : p += 4; 59 : } 60 : #endif /* __x86_64__ */ 61 : 62 : /* Process any remaining bytes one at a time. */ 63 318086596 : while (p < pend) 64 : { 65 161348692 : crc = _mm_crc32_u8(crc, *p); 66 161348692 : p++; 67 : } 68 : 69 156737904 : return crc; 70 : }