[fpc-pascal] Fast CRC functions?

Juha Manninen juha.manninen62 at gmail.com
Mon Aug 25 10:46:15 CEST 2014


We have an old function for calculating CRC like:

function CalcCRC(const Str: String): Cardinal;
var
  Len, i, CRCVal: Cardinal;
Begin
  Len := Length(Str);
  CRCVal := $FFFFFFFF;
  if Len > 0 then
    for i := 1 to Len do
      CRCVal := CRCTbl[Byte(CRCVal xor Cardinal(Str[i]))] xor ((CRCVal
shr 8) and $00FFFFFF);
  Result := not(CRCVal);
end;

"CRCTbl" is a table with hex numbers.

Then I tested a new super-fast function crc32c() from Synopse mORMot
lib that uses Intel SSE instructions:

  http://blog.synopse.info/post/2014/05/25/New-crc32c%28%29-function-using-optimized-asm-and-SSE-4.2-instruction

Wow, with long input data strings it is 10 * faster!
But, bummer, it returns a different value. :(
Our CRCs are stored around in DBs and we need the same value.

I thought CRC algorith is a standard but apparently not.
It says at the Synopse blog-page:
---
In fact, most popular file formats and protocols (Ethernet, MPEG-2,
ZIP, RAR, 7-Zip, GZip, and PNG) use the polynomial $04C11DB7, while
Intel's hardware implementation is based on another polynomial,
$1EDC6F41 (used in iSCSI and Btrfs).
So you would not use this new crc32c() function to replace the zlib's
crc32() function, but as a convenient very fast hashing function at
application level.
For instance, our TDynArray wrapper will use it for fast items hashing.
---

I don't know what the "polynomial" does here. Does it mean Intel CPUs
have built-in support for specific CRC calculations?

Does anybody know of other optimized CRC functions?
We would love the speedup.

Regards,
Juha



More information about the fpc-pascal mailing list