Merge pull request #44 from Demogorgon314/perf-bt-crc-hotpath

Replace runtime CRC32 table setup with a constexpr lookup table for faster output and feature report checksums
This commit is contained in:
awalol
2026-05-08 20:30:16 +08:00
committed by GitHub
+27 -15
View File
@@ -2,6 +2,7 @@
// Created by awalol on 2026/3/4.
//
#include <array>
#include <cstdint>
#include <iomanip>
#include <iostream>
@@ -89,18 +90,37 @@ inline const char *opcode_to_str(const uint16_t opcode) {
}
}
inline uint32_t crc32(const uint8_t* data, size_t size) {
uint32_t crc = ~0xEADA2D49; // 0xA2 seed
inline constexpr uint32_t crc32_table_entry(uint32_t index) {
for (unsigned bit = 0; bit < 8; ++bit) {
index = (index >> 1) ^ (0xEDB88320 & -(index & 1));
}
return index;
}
inline constexpr auto make_crc32_table() {
std::array<uint32_t, 256> table{};
for (uint32_t i = 0; i < table.size(); ++i) {
table[i] = crc32_table_entry(i);
}
return table;
}
inline constexpr auto crc32_lookup_table = make_crc32_table();
inline uint32_t crc32_seeded(const uint8_t *data, size_t size, const uint32_t seed) {
uint32_t crc = ~seed;
while (size--) {
crc ^= *data++;
for (unsigned i = 0; i < 8; i++)
crc = ((crc >> 1) ^ (0xEDB88320 & -(crc & 1)));
crc = (crc >> 8) ^ crc32_lookup_table[(crc ^ *data++) & 0xff];
}
return ~crc;
}
inline uint32_t crc32(const uint8_t* data, size_t size) {
return crc32_seeded(data, size, 0xEADA2D49); // 0xA2 seed
}
inline void fill_output_report_checksum(uint8_t* outputData,size_t len)
{
uint32_t crc = crc32(outputData, len - 4);
@@ -112,15 +132,7 @@ inline void fill_output_report_checksum(uint8_t* outputData,size_t len)
inline uint32_t crc32_feature(const uint8_t *data, std::size_t size) {
// https://github.com/rafaelvaloto/Dualsense-Multiplatform/blob/main/Source/Private/GCore/Utils/CR32.cpp
uint32_t crc = ~0x2060efc3; // 0x53 seed
while (size--) {
crc ^= *data++;
for (unsigned i = 0; i < 8; i++)
crc = ((crc >> 1) ^ (0xEDB88320 & -(crc & 1)));
}
return ~crc;
return crc32_seeded(data, size, 0x2060efc3); // 0x53 seed
}
inline void fill_feature_report_checksum(uint8_t *data, const size_t len) {
@@ -242,4 +254,4 @@ inline void print_hex(const uint8_t* data,size_t size) {
std::cout << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(data[i]) << " ";
}
std::cout << std::endl;
}
}