Re: What exactly is our CRC algorithm? - Mailing list pgsql-hackers

From Andres Freund
Subject Re: What exactly is our CRC algorithm?
Date
Msg-id 20141229122228.GA27028@alap3.anarazel.de
Whole thread Raw
In response to Re: What exactly is our CRC algorithm?  (Abhijit Menon-Sen <ams@2ndQuadrant.com>)
Responses Re: What exactly is our CRC algorithm?  (Abhijit Menon-Sen <ams@2ndQuadrant.com>)
List 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



pgsql-hackers by date:

Previous
From: Andres Freund
Date:
Subject: Re: [COMMITTERS] pgsql: Keep track of transaction commit timestamps
Next
From: Abhijit Menon-Sen
Date:
Subject: Re: What exactly is our CRC algorithm?