Re: What exactly is our CRC algorithm?

From: Andres Freund <andres(at)2ndquadrant(dot)com>
To: Abhijit Menon-Sen <ams(at)2ndQuadrant(dot)com>
Cc: pgsql-hackers(at)postgresql(dot)org, Heikki Linnakangas <hlinnakangas(at)vmware(dot)com>, Robert Haas <robertmhaas(at)gmail(dot)com>
Subject: Re: What exactly is our CRC algorithm?
Date: 2014-12-29 12:22:28
Message-ID: 20141229122228.GA27028@alap3.anarazel.de
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi,

On 2014-12-25 11:57:29 +0530, Abhijit Menon-Sen wrote:
> -extern pg_crc32 pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len);
> +extern void pg_init_comp_crc32c(void);

How about pg_choose_crc_impl() or something?

> +extern pg_crc32 (*pg_comp_crc32c)(pg_crc32 crc, const void *data, size_t len);
>
> /*
> * CRC calculation using the CRC-32C (Castagnoli) polynomial.
>
> diff --git a/src/port/pg_crc.c b/src/port/pg_crc.c
> index 2f9857b..6be17b0 100644
> --- a/src/port/pg_crc.c
> +++ b/src/port/pg_crc.c
> @@ -21,6 +21,13 @@
> #include "utils/pg_crc.h"
> #include "utils/pg_crc_tables.h"
>
> +#if defined(HAVE_CPUID_H)
> +#include <cpuid.h>
> +#elif defined(_MSC_VER)
> +#include <intrin.h>
> +#include <nmmintrin.h>
> +#endif
> +
> static inline uint32 bswap32(uint32 x)
> {
> #if defined(__GNUC__) || defined(__clang__)
> @@ -39,8 +46,8 @@ static inline uint32 bswap32(uint32 x)
> #define cpu_to_le32(x) x
> #endif
>
> -pg_crc32
> -pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len)
> +static pg_crc32
> +pg_comp_crc32c_sb8(pg_crc32 crc, const void *data, size_t len)

_sb8? Unless I miss something it's not slice by 8 but rather bytewise?

> {
> const unsigned char *p = data;
> const uint32 *p8;
> @@ -61,7 +68,6 @@ pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len)
> */
>
> p8 = (const uint32 *) p;
> -
> while (len >= 8)
> {
> uint32 a = *p8++ ^ cpu_to_le32(crc);
> @@ -101,8 +107,102 @@ pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len)
> */
>
> p = (const unsigned char *) p8;
> - while (len-- > 0)
> + while (len > 0)
> + {
> crc = pg_crc32c_table[0][(crc ^ *p++) & 0xFF] ^ (crc >> 8);
> + len--;
> + }
> +
> + return crc;
> +}
>
> +static pg_crc32
> +pg_asm_crc32b(pg_crc32 crc, unsigned char data)
> +{

Should be marked inline.

> +#ifdef __GNUC__
> + __asm__ ("crc32b %[data], %[crc]\n" : [crc] "+r" (crc) : [data] "rm" (data));

Have you checked which version of gcc introduced named references to
input/output parameters?

> return crc;
> +#elif defined(_MSC_VER)
> + return _mm_crc32_u8(crc, data);
> +#else
> +#error "Don't know how to generate crc32b instruction"
> +#endif
> }
> +
> +static pg_crc32
> +pg_asm_crc32q(uint64 crc, unsigned long long data)
> +{

inline.

Greetings,

Andres Freund

--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Abhijit Menon-Sen 2014-12-29 13:14:18 Re: What exactly is our CRC algorithm?
Previous Message Andres Freund 2014-12-29 12:14:10 Re: [COMMITTERS] pgsql: Keep track of transaction commit timestamps