bsidesbadge/lib/crc32/Crc32Test.cpp

171 lines
5.2 KiB
C++

// //////////////////////////////////////////////////////////
// Crc32Test.cpp
// Copyright (c) 2016-2019 Stephan Brumme. All rights reserved.
// see http://create.stephan-brumme.com/disclaimer.html
//
#include "Crc32.h"
#include <cstdlib>
#include <cstdio>
// the slicing-by-4/8/16 tests are only performed if the corresponding
// preprocessor symbol is defined in Crc32.h
// simpler algorithms can be enabled/disabled right here:
#define CRC32_TEST_BITWISE
#define CRC32_TEST_HALFBYTE
#define CRC32_TEST_TABLELESS
// //////////////////////////////////////////////////////////
// test code
/// one gigabyte
const size_t NumBytes = 1024*1024*1024;
/// 4k chunks during last test
const size_t DefaultChunkSize = 4*1024;
#if defined(_WIN32) || defined(_WIN64)
#include <windows.h>
#else
#include <ctime>
#endif
// timing
static double seconds()
{
#if defined(_WIN32) || defined(_WIN64)
LARGE_INTEGER frequency, now;
QueryPerformanceFrequency(&frequency);
QueryPerformanceCounter (&now);
return now.QuadPart / double(frequency.QuadPart);
#else
timespec now;
clock_gettime(CLOCK_REALTIME, &now);
return now.tv_sec + now.tv_nsec / 1000000000.0;
#endif
}
int main(int, char**)
{
printf("Please wait ...\n");
uint32_t randomNumber = 0x27121978;
// initialize
char* data = new char[NumBytes];
for (size_t i = 0; i < NumBytes; i++)
{
data[i] = char(randomNumber & 0xFF);
// simple LCG, see http://en.wikipedia.org/wiki/Linear_congruential_generator
randomNumber = 1664525 * randomNumber + 1013904223;
}
// re-use variables
double startTime, duration;
uint32_t crc;
#ifdef CRC32_TEST_BITWISE
// bitwise
startTime = seconds();
crc = crc32_bitwise(data, NumBytes);
duration = seconds() - startTime;
printf("bitwise : CRC=%08X, %.3fs, %.3f MB/s\n",
crc, duration, (NumBytes / (1024*1024)) / duration);
#endif // CRC32_TEST_BITWISE
#ifdef CRC32_TEST_HALFBYTE
// half-byte
startTime = seconds();
crc = crc32_halfbyte(data, NumBytes);
duration = seconds() - startTime;
printf("half-byte : CRC=%08X, %.3fs, %.3f MB/s\n",
crc, duration, (NumBytes / (1024*1024)) / duration);
#endif // CRC32_TEST_HALFBYTE
#ifdef CRC32_TEST_TABLELESS
// one byte at once (without lookup tables)
startTime = seconds();
crc = crc32_1byte_tableless(data, NumBytes);
duration = seconds() - startTime;
printf("tableless (byte) : CRC=%08X, %.3fs, %.3f MB/s\n",
crc, duration, (NumBytes / (1024*1024)) / duration);
// one byte at once (without lookup tables)
startTime = seconds();
crc = crc32_1byte_tableless2(data, NumBytes);
duration = seconds() - startTime;
printf("tableless (byte2): CRC=%08X, %.3fs, %.3f MB/s\n",
crc, duration, (NumBytes / (1024*1024)) / duration);
#endif // CRC32_TEST_TABLELESS
#ifdef CRC32_USE_LOOKUP_TABLE_BYTE
// one byte at once
startTime = seconds();
crc = crc32_1byte(data, NumBytes);
duration = seconds() - startTime;
printf(" 1 byte at once: CRC=%08X, %.3fs, %.3f MB/s\n",
crc, duration, (NumBytes / (1024*1024)) / duration);
#endif // CRC32_USE_LOOKUP_TABLE_BYTE
#ifdef CRC32_USE_LOOKUP_TABLE_SLICING_BY_4
// four bytes at once
startTime = seconds();
crc = crc32_4bytes(data, NumBytes);
duration = seconds() - startTime;
printf(" 4 bytes at once: CRC=%08X, %.3fs, %.3f MB/s\n",
crc, duration, (NumBytes / (1024*1024)) / duration);
#endif // CRC32_USE_LOOKUP_TABLE_SLICING_BY_4
#ifdef CRC32_USE_LOOKUP_TABLE_SLICING_BY_8
// eight bytes at once
startTime = seconds();
crc = crc32_8bytes(data, NumBytes);
duration = seconds() - startTime;
printf(" 8 bytes at once: CRC=%08X, %.3fs, %.3f MB/s\n",
crc, duration, (NumBytes / (1024*1024)) / duration);
// eight bytes at once, unrolled 4 times (=> 32 bytes per loop)
startTime = seconds();
crc = crc32_4x8bytes(data, NumBytes);
duration = seconds() - startTime;
printf("4x8 bytes at once: CRC=%08X, %.3fs, %.3f MB/s\n",
crc, duration, (NumBytes / (1024*1024)) / duration);
#endif // CRC32_USE_LOOKUP_TABLE_SLICING_BY_8
#ifdef CRC32_USE_LOOKUP_TABLE_SLICING_BY_16
// sixteen bytes at once
startTime = seconds();
crc = crc32_16bytes(data, NumBytes);
duration = seconds() - startTime;
printf(" 16 bytes at once: CRC=%08X, %.3fs, %.3f MB/s\n",
crc, duration, (NumBytes / (1024*1024)) / duration);
// sixteen bytes at once
startTime = seconds();
crc = crc32_16bytes_prefetch(data, NumBytes, 0, 256);
duration = seconds() - startTime;
printf(" 16 bytes at once: CRC=%08X, %.3fs, %.3f MB/s (including prefetching)\n",
crc, duration, (NumBytes / (1024*1024)) / duration);
#endif // CRC32_USE_LOOKUP_TABLE_SLICING_BY_16
// process in 4k chunks
startTime = seconds();
crc = 0; // also default parameter of crc32_xx functions
size_t bytesProcessed = 0;
while (bytesProcessed < NumBytes)
{
size_t bytesLeft = NumBytes - bytesProcessed;
size_t chunkSize = (DefaultChunkSize < bytesLeft) ? DefaultChunkSize : bytesLeft;
crc = crc32_fast(data + bytesProcessed, chunkSize, crc);
bytesProcessed += chunkSize;
}
duration = seconds() - startTime;
printf(" chunked : CRC=%08X, %.3fs, %.3f MB/s\n",
crc, duration, (NumBytes / (1024*1024)) / duration);
delete[] data;
return 0;
}