Stačí kliknout na ten odkaz a je to tam napsané:
- The first thing I tried was using compiler optimizations for the CRC routines (GCC's -O3 instead of -Os)
- I then started looking for optimized CRC algorithms and found Matt Stancliff's crcspeed repository. It is based on an algorithm developed by Intel that uses additional lookup tables to enable processing of multiple input bytes in a single step.
Ta původní implementace byla "by book".
https://github.com/mattsta/crcspeed/blob/master/crcspeed.c#L32
/* Fill in a CRC constants table. */ void crcspeed64little_init(crcfn64 crcfn, uint64_t table[8][256]) { uint64_t crc; /* generate CRCs for all single byte sequences */ for (int n = 0; n < 256; n++) { table[0][n] = crcfn(0, &n, 1); } /* generate nested CRC table for future slice-by-8 lookup */ for (int n = 0; n < 256; n++) { crc = table[0][n]; for (int k = 1; k < 8; k++) { crc = table[0][crc & 0xff] ^ (crc >> 8); table[k][n] = crc; } } }
Pre lorem ipsum z unit testu to bude asi signifikantny cas, ale pre 700MB+ subor z vyssie uvedeneho testu to nebude nic strasne.
CRC tabulky netreba pocitat az po zavleceni kodu, mnohem efektivnejsi je mit je jiz predpocitane (jsou nezavisle na zpracovavanych datech) a ulozene tesne za rutinou vypoctu CRC. Pak se vam do cache zatahnou spolecne s kodem a jedete (pro CRC16 Slicing-by-8 se jedna o 8 x 256 x 2 = 4 kB). Na tri roky stare i7 jsem dosahoval rychlosti vypoctu CRC Slicing-by-16 nekde kolem 0.1 periody hodin CPU na bit, tj. asi 30 Gbit/s pri danem taktu i7. Udaje plati pro pouziti pouze jednoho jadra i7 a dat v cache. Jeden by se divil, proc u casove kritickych aplikaci stale jeste nekdo nasazuje primitivní one-LUT metodu, kdyz clanku od Intelu uz je 13 let a Slicing-by-X algoritmy se "vali temer v kazdem GITu" na webu. Odkaz na puvodni zdroj Intel: https://pdfs.semanticscholar.org/2e14/46ec7ee9825e30e6188974903d6486655dee.pdf , original na Intelim FTP neni dostupny.