Giter VIP home page Giter VIP logo

crcspeed's Introduction

crcspeed

CRC be slow.

This make CRC be fast.

No original ideas, but original adaptations. Lots of shoulder standing.

This started out as a modified version of comment at http://stackoverflow.com/questions/20562546 then was made more extensible.

NOTE: You should not be using any CRC variant for new code anywhere. All new fast hashing code should use well-designed multi-platform simd-aware libraries like xxh3 and xxh128. Only use CRC in your code if you need to hack together adapters for existing poorly designed systems or if you find yourself time travelling back to the 1970s.

Feature

  • CRC processing in 8-byte steps for CRC-64 (Jones) and CRC-16 (CCITT).
  • Generates CRCs with overhead of 1.5 CPU cycles per byte
  • Little endian and big endian support
    • big endian support hasn't been tested yet (because qemu-system-sparc hates me).
  • Test suite generates comparison for: bit-by-bit calculation, byte-by-byte calcuation (Sarwate / lookup table), and 8-bytes-at-once calculation. Results are reported with resulting CRCs, throughput, and CPU cycles per byte comparisons.

Usage

  • Use little endian CRCs:
    • crc64speed_init();
    • crc64speed(old_crc, new_data, new_data_length);
    • crc16speed_init();
    • crc16speed(old_crc, new_data, new_data_length);
  • Use native architecture CRCs:
    • crc64speed_init_native();
    • crc64speed_native(old_crc, new_data, new_data_length);
    • crc16speed_init_native();
    • crc16speed_native(old_crc, new_data, new_data_length);
  • Use custom CRC64 variant:
    • crcspeed64native_init(crc_calculation_function, uint64_t populate[8][256]);
      • crc calculation function takes (0, data, data_len) and returns crc64 as uint64_t.
      • populate is a lookup table _init populates for future lookups.
    • crcspeed64native(populated_lookup_table, old_crc, new_data, new_data_length);
  • Use custom CRC16 parameters:
    • crcspeed16native_init(crc_calculation_function, uint16_t populate[8][256]);
      • crc calculation function takes (0, data, data_len) and returns crc16 as uint16_t.
    • crcspeed16native(populated_lookup_table, old_crc, new_data, new_data_length);

Additionally, there are specific functions for forcing little or big endian calculations: crcspeed64little_init(), crcspeed64little(), crc64big_init(), crcspeed64big(), crcspeed16little_init(), crcspeed16little(), crc16big_init(), crcspeed16big().

Architecture

  • crcspeed.c is a framework for bootstrapping a fast lookup table using an existing function used to return the CRC for byte values 0 to 255. Lookups then use fast lookup table to calculate CRCs 8 bytes per loop iteration.
  • crc64speed.c is a ready-to-use fast, self-contained CRC-64-Jones implementation.
  • crc16speed.c is a ready-to-use fast, self-contained CRC16-CCITT implementation.
  • when in a multithreaded environment, do not run initialization function(s) in parallel.
  • for fastest CRC calculations, you can force the entire CRC lookup table into CPU caches by running crc64speed_cache_table() or crc16speed_cache_table(). Those functions just iterate over the lookup table to bring everything into local caches out from main memory (or worse, paged out to disk).
  • The CRC-16 lookup table is 4 KB (8x256 16 bit entries = 8 * 256 * 2 bytes = 4096 bytes).
  • The CRC-64 lookup table is 16 KB (8x256 64 bit entires = 8 * 256 * 8 bytes = 16384 bytes).

Benchmark

The Makefile builds three test excutables:

  • crc64speed just returns check values for two input types across all three internal CRC process methods (bit-by-bit, byte-by-byte, 8-bytes-at-once).
  • crc16speed returns check values for the same data, except limited to CRC16 results.
  • crcspeed has two options:
    • no arguments: return check values for crc64 and crc16 at the same time.
    • one argument: filename of file to read into memory then run CRC tests against.
      • If CRC results do not match (for each CRC variant), the return value of crcspeed is 1, otherwise 0 on success.
> mkdir build
> cd build
> cmake ..
> make -j
[ 18%] Building C object CMakeFiles/crcspeed.dir/crc16speed.c.o
[ 27%] Building C object CMakeFiles/crcspeed.dir/crcspeed.c.o
[ 36%] Building C object CMakeFiles/crcspeed.dir/crc64speed.c.o
[ 54%] Building C object CMakeFiles/crc64speed.dir/crc64speed.c.o
[ 54%] Building C object CMakeFiles/crc64speed.dir/crcspeed.c.o
[ 54%] Building C object CMakeFiles/crc16speed.dir/crcspeed.c.o
[ 63%] Building C object CMakeFiles/crc16speed.dir/crc16speed.c.o
[ 72%] Building C object CMakeFiles/crcspeed.dir/main.c.o
[ 81%] Linking C executable crc64speed
[ 90%] Linking C executable crc16speed
[100%] Linking C executable crcspeed
[100%] Built target crc16speed
[100%] Built target crc64speed
[100%] Built target crcspeed

> ./crcspeed ~/Downloads/John\ Mayer\ -\ Live\ At\ Austin\ City\ Limits\ PBS\ -\ Full\ Concert-gcdUz12FkdQ.mp4
Comparing CRCs against 730.72 MB file...

crc64 (no table)
CRC = ee43263b0a2b6c60
7.142642 seconds at 102.30 MB/s (24.18 CPU cycles per byte)

crc64 (lookup table)
CRC = ee43263b0a2b6c60
1.777920 seconds at 411.00 MB/s (6.02 CPU cycles per byte)

crc64speed
CRC = ee43263b0a2b6c60
0.448819 seconds at 1628.09 MB/s (1.52 CPU cycles per byte)

crc16 (no table)
CRC = 000000000000490f
7.413062 seconds at 98.57 MB/s (25.10 CPU cycles per byte)

crc16 (lookup table)
CRC = 000000000000490f
1.951917 seconds at 374.36 MB/s (6.61 CPU cycles per byte)

crc16speed
CRC = 000000000000490f
0.441418 seconds at 1655.38 MB/s (1.49 CPU cycles per byte)

License

All work here is released under BSD or Apache 2.0 License or equivalent.

Thanks

Thanks to Mark Adler for providing a readable implementation of slicing-by-8 in a stackoverflow comment.

Thanks for pycrc for saving me another month figuring out how to write CRC-64-Jones by hand.

Thanks to A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS for providing so many details it was clear I should give up and not try to re-create everything myself.

crcspeed's People

Contributors

anonyco avatar mattsta avatar znikke avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

crcspeed's Issues

License for the code

Hi @mattsta!

I was having a look at your code, as I would be interested in using it to calculate the CRC64 to generate RDB files but I have noticed that the license on the files, i just 2 of them, refers to Redis but this repo is not under the Redis Labs organization or under the Redis project.

Specifically both crc16speed.c and crc64speed.c refer Redis in the license meanwhile crcspeed.c has a different license and the header files have no license.

Was it because of a copy & paste or is the code owner by Redis Labs?

Disclaimer:
I am implementing in my Key-Value store, it's called cachegrand ( https://github.com/danielealbano/cachegrand ) and as I am to make it Redis compatible I am adding the necessary bits and pieces to load and save RDB dumps.
Of course to have full compatibility I would like to have the CRC64 generation and check but after quite a while attempting to validate the RDB generated by my code with redis-check-rdb I discovered I was using a different polynomial (I am not an expert with CRC64) and after multiple attempts, even with pycrc, I wasn't able to make it work.

If it's a copy & paste I can make a PR to fix it, if not, thanks for the time spent reading my message :)

CRC16 test reports ERROR, likely because 32 bits are printed/used as CRC16 checksum

The accelerated CRC16 implementation seems to be misbehaving. I get CRC errors regardless of which files are used, for the below examples I've used the 60k test file http://ftp.acc.umu.se/mirror/media/StarWreck-InThePirkinning/star_wreck_in_the_pirkinning_subtitles_eng.srt (Creative Commons licensed).

However, I think that the errors are benign as CRC16 is 2 bytes, and all mismatches I've seen seems to be in the additional 2 bytes that are emitted for some reason. Coding cleanup gone wrong?

I don't think it's a compiler/CPU-specific issue, as I'm seeing this on various machines. The examples below are a git pull of this repo and make clean; make to have the crc*speed-test binaries compiled on each platform.

RHEL 6.7, Intel E5-2643:

crc16 (no table)
CRC = 0000000022dda97d
0.002447 seconds at 23.98 MB/s (131.23 CPU cycles per byte)

crc16 (lookup table)
CRC = 000000002ddaa97d
0.000250 seconds at 234.70 MB/s (13.38 CPU cycles per byte)
ERROR: CRC results don't match! (0000000022dda97d vs. 000000002ddaa97d)

crc16speed
CRC = 000000002ddaa97d
0.000052 seconds at 1128.34 MB/s (2.80 CPU cycles per byte)
ERROR: CRC results don't match! (0000000022dda97d vs. 000000002ddaa97d)

Ubuntu 14.04.5 LTS, Intel E5-2630:

crc16 (no table)
CRC = 0000000022dda97d
0.004516 seconds at 12.99 MB/s (168.45 CPU cycles per byte)

crc16 (lookup table)
CRC = 000000002ddaa97d
0.000514 seconds at 114.15 MB/s (19.17 CPU cycles per byte)
ERROR: CRC results don't match! (0000000022dda97d vs. 000000002ddaa97d)

crc16speed
CRC = 000000002ddaa97d
0.000103 seconds at 569.65 MB/s (3.85 CPU cycles per byte)
ERROR: CRC results don't match! (0000000022dda97d vs. 000000002ddaa97d)

Ubuntu 16.04.2 LTS, Intel E5-2620 v4:

crc16 (no table)
CRC = 0000000022dda97d
0.004750 seconds at 12.35 MB/s (162.13 CPU cycles per byte)

crc16 (lookup table)
CRC = 000000002ddaa97d
0.000513 seconds at 114.37 MB/s (17.50 CPU cycles per byte)
ERROR: CRC results don't match! (0000000022dda97d vs. 000000002ddaa97d)

crc16speed
CRC = 000000002ddaa97d
0.000071 seconds at 826.39 MB/s (2.42 CPU cycles per byte)
ERROR: CRC results don't match! (0000000022dda97d vs. 000000002ddaa97d)

crc16speed.c

static uint16_t crc16_table_little[8][256] = {{0}};
static uint16_t crc16_table_big[8][256] = {{0}};

Я бы хранил уже посчитанные

static constexpr uint16_t crc16_table_little[][256]{
    {...},
};
static constexpr uint16_t crc16_table_big[][256]{
    {...},
};

The CRC-16 of string name of Li is not the same, need to be verified.

I have check more implements of CRC-CCITT
POLYNOMIAL:0x1021,
INITIAL:0x0000,
FINAL_XOR_VALUE:0x0000,
Little endian.

For char test="123456789", the crc result is # 0x31c3
For char li[] = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed "
"do eiusmod tempor incididunt ut labore et dolore magna "
"aliqua. Ut enim ad minim veniam, quis nostrud exercitation "
"ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis "
"aute irure dolor in reprehenderit in voluptate velit esse "
"cillum dolore eu fugiat nulla pariatur. Excepteur sint "
"occaecat cupidatat non proident, sunt in culpa qui officia "
"deserunt mollit anim id est laborum.", the crc result is # 0x224f

you can check them:
http://www.sunshine2k.de/coding/javascript/crc/crc_js.html
http://www.barrgroup.com/Embedded-Systems/How-To/CRC-Calculation-C-Code

So i think your result for string Li of 4b20 is not correct.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.