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-2024, 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_crc32c 23 156243156 : pg_comp_crc32c_sse42(pg_crc32c crc, const void *data, size_t len) 24 : { 25 156243156 : const unsigned char *p = data; 26 156243156 : const unsigned char *pend = p + len; 27 : 28 : /* 29 : * Process eight bytes of data at a time. 30 : * 31 : * NB: We do unaligned accesses here. The Intel architecture allows that, 32 : * and performance testing didn't show any performance gain from aligning 33 : * the begin address. 34 : */ 35 : #ifdef __x86_64__ 36 7502270680 : while (p + 8 <= pend) 37 : { 38 7346027524 : crc = (uint32) _mm_crc32_u64(crc, *((const uint64 *) p)); 39 7346027524 : p += 8; 40 : } 41 : 42 : /* Process remaining full four bytes if any */ 43 156243156 : if (p + 4 <= pend) 44 : { 45 93387762 : crc = _mm_crc32_u32(crc, *((const unsigned int *) p)); 46 93387762 : p += 4; 47 : } 48 : #else 49 : 50 : /* 51 : * Process four bytes at a time. (The eight byte instruction is not 52 : * available on the 32-bit x86 architecture). 53 : */ 54 : while (p + 4 <= pend) 55 : { 56 : crc = _mm_crc32_u32(crc, *((const unsigned int *) p)); 57 : p += 4; 58 : } 59 : #endif /* __x86_64__ */ 60 : 61 : /* Process any remaining bytes one at a time. */ 62 317124812 : while (p < pend) 63 : { 64 160881656 : crc = _mm_crc32_u8(crc, *p); 65 160881656 : p++; 66 : } 67 : 68 156243156 : return crc; 69 : }