三个32位整数的最快16位校验和

时间:2019-12-31 00:24:42

标签: c optimization profiling crc cortex-m

假设我在Cortex M4处理器上(使用GCC 7)有很多24B块,并且我想计算一个快速的16位校验和,那么比CRC16 CCITT更快的替代方法是什么?现在,CRC-16(使用256元素的查找表)比创建缓冲区要花费更多的时间(我在这里显然是在谈论微秒,但是这些块应该以尽可能低的延迟生成,并且通过剖析可以到达那里)

我尝试展开CRC,但是它仍然需要遍历所有24个字节(2个移位,2个xor,1和1个表查找,重复24x):

uint16_t crc16_24B_unrolled(uint16_t seed, const char *data)
{
    uint16_t crc = seed;

    crc = (u16)((crc << 8) ^ crc16tab[((crc >> 8) ^ data[0]) & 0x00FF]);
    crc = (u16)((crc << 8) ^ crc16tab[((crc >> 8) ^ data[1]) & 0x00FF]);
    crc = (u16)((crc << 8) ^ crc16tab[((crc >> 8) ^ data[2]) & 0x00FF]);
    ... (24 times)

    return crc;
}

由于数据是对齐的,并且是32位处理器,所以我认为也许我可以创建一个更简单的校验和,类似以下内容:

uint16_t data_get_chksum(const char *data)
{
     // data is guaranteed to be aligned to 8B
     // (although Cortex M4 supports unaligned int access)
     const uint32_t * ptr32 = (const uint32_t *)data;

     // just add three 32-bit integers
     uint32_t chk = 0xa7f72f28; // <-- made up for the purpose of this question
     chk += *ptr32++;
     chk += *ptr32++;
     chk += *ptr32;

     // xor high and low words
     return (uint16_t)((chk >> 16) ^ (chk));   
}

加法和XORing显然被认为是进行校验和/散列的一种较差的方法,但是在这种情况下,如果我能获得较大的加速,我愿意得到一些误报(校验和在读​​取时被错误地报告为有效)。这些校验和不需要像CCITT那样是标准的,它们用于检查这些块在重启后是否有效,并将它们放置在标记为非易失性的区域中。

0 个答案:

没有答案