Add hardware crc impl
[folly.git] / folly / test / ChecksumTest.cpp
index 0c4747d7868903820fc12e467c0a5bfd880a92f9..4c5039a2198dc0285186b010eeab899f910a9d8e 100644 (file)
@@ -126,6 +126,49 @@ TEST(Checksum, crc32c_continuation_autodetect) {
   testCRC32CContinuation(folly::crc32c);
 }
 
   testCRC32CContinuation(folly::crc32c);
 }
 
+TEST(Checksum, crc32) {
+  if (folly::detail::crc32c_hw_supported()) {
+    // Just check that sw and hw match
+    for (auto expected : expectedResults) {
+      uint32_t sw_res =
+          folly::detail::crc32_sw(buffer + expected.offset, expected.length, 0);
+      uint32_t hw_res =
+          folly::detail::crc32_hw(buffer + expected.offset, expected.length, 0);
+      EXPECT_EQ(sw_res, hw_res);
+    }
+  } else {
+    LOG(WARNING) << "skipping hardware-accelerated CRC-32 tests"
+                 << " (not supported on this CPU)";
+  }
+}
+
+TEST(Checksum, crc32_continuation) {
+  if (folly::detail::crc32c_hw_supported()) {
+    // Just check that sw and hw match
+    for (auto expected : expectedResults) {
+      auto halflen = expected.length / 2;
+      uint32_t sw_res =
+          folly::detail::crc32_sw(buffer + expected.offset, halflen, 0);
+      sw_res = folly::detail::crc32_sw(
+          buffer + expected.offset + halflen, halflen, sw_res);
+      uint32_t hw_res =
+          folly::detail::crc32_hw(buffer + expected.offset, halflen, 0);
+      hw_res = folly::detail::crc32_hw(
+          buffer + expected.offset + halflen, halflen, hw_res);
+      EXPECT_EQ(sw_res, hw_res);
+      uint32_t sw_res2 =
+          folly::detail::crc32_sw(buffer + expected.offset, halflen * 2, 0);
+      EXPECT_EQ(sw_res, sw_res2);
+      uint32_t hw_res2 =
+          folly::detail::crc32_hw(buffer + expected.offset, halflen * 2, 0);
+      EXPECT_EQ(hw_res, hw_res2);
+    }
+  } else {
+    LOG(WARNING) << "skipping hardware-accelerated CRC-32 tests"
+                 << " (not supported on this CPU)";
+  }
+}
+
 void benchmarkHardwareCRC32C(unsigned long iters, size_t blockSize) {
   if (folly::detail::crc32c_hw_supported()) {
     uint32_t checksum;
 void benchmarkHardwareCRC32C(unsigned long iters, size_t blockSize) {
   if (folly::detail::crc32c_hw_supported()) {
     uint32_t checksum;
@@ -147,6 +190,27 @@ void benchmarkSoftwareCRC32C(unsigned long iters, size_t blockSize) {
   }
 }
 
   }
 }
 
+void benchmarkHardwareCRC32(unsigned long iters, size_t blockSize) {
+  if (folly::detail::crc32_hw_supported()) {
+    uint32_t checksum;
+    for (unsigned long i = 0; i < iters; i++) {
+      checksum = folly::detail::crc32_hw(buffer, blockSize);
+      folly::doNotOptimizeAway(checksum);
+    }
+  } else {
+    LOG(WARNING) << "skipping hardware-accelerated CRC-32 benchmarks"
+                 << " (not supported on this CPU)";
+  }
+}
+
+void benchmarkSoftwareCRC32(unsigned long iters, size_t blockSize) {
+  uint32_t checksum;
+  for (unsigned long i = 0; i < iters; i++) {
+    checksum = folly::detail::crc32_sw(buffer, blockSize);
+    folly::doNotOptimizeAway(checksum);
+  }
+}
+
 // This test fits easily in the L1 cache on modern server processors,
 // and thus it mainly measures the speed of the checksum computation.
 BENCHMARK(crc32c_hardware_1KB_block, iters) {
 // This test fits easily in the L1 cache on modern server processors,
 // and thus it mainly measures the speed of the checksum computation.
 BENCHMARK(crc32c_hardware_1KB_block, iters) {
@@ -157,6 +221,14 @@ BENCHMARK(crc32c_software_1KB_block, iters) {
   benchmarkSoftwareCRC32C(iters, 1024);
 }
 
   benchmarkSoftwareCRC32C(iters, 1024);
 }
 
+BENCHMARK(crc32_hardware_1KB_block, iters) {
+  benchmarkHardwareCRC32(iters, 1024);
+}
+
+BENCHMARK(crc32_software_1KB_block, iters) {
+  benchmarkSoftwareCRC32(iters, 1024);
+}
+
 BENCHMARK_DRAW_LINE();
 
 // This test is too big for the L1 cache but fits in L2
 BENCHMARK_DRAW_LINE();
 
 // This test is too big for the L1 cache but fits in L2
@@ -168,6 +240,14 @@ BENCHMARK(crc32c_software_64KB_block, iters) {
   benchmarkSoftwareCRC32C(iters, 64 * 1024);
 }
 
   benchmarkSoftwareCRC32C(iters, 64 * 1024);
 }
 
+BENCHMARK(crc32_hardware_64KB_block, iters) {
+  benchmarkHardwareCRC32(iters, 64 * 1024);
+}
+
+BENCHMARK(crc32_software_64KB_block, iters) {
+  benchmarkSoftwareCRC32(iters, 64 * 1024);
+}
+
 BENCHMARK_DRAW_LINE();
 
 // This test is too big for the L2 cache but fits in L3
 BENCHMARK_DRAW_LINE();
 
 // This test is too big for the L2 cache but fits in L3
@@ -179,6 +259,13 @@ BENCHMARK(crc32c_software_512KB_block, iters) {
   benchmarkSoftwareCRC32C(iters, 512 * 1024);
 }
 
   benchmarkSoftwareCRC32C(iters, 512 * 1024);
 }
 
+BENCHMARK(crc32_hardware_512KB_block, iters) {
+  benchmarkHardwareCRC32(iters, 512 * 1024);
+}
+
+BENCHMARK(crc32_software_512KB_block, iters) {
+  benchmarkSoftwareCRC32(iters, 512 * 1024);
+}
 
 int main(int argc, char** argv) {
   testing::InitGoogleTest(&argc, argv);
 
 int main(int argc, char** argv) {
   testing::InitGoogleTest(&argc, argv);