ARMv8 CRC32指令集测试

在PINE 64上测试了一下ARMv8的 CRC32加速代码,大约可以获得6倍的加速,可以用于压缩和以太网校验算法的加速

测试代码如下,来自linux kernel arch/arm64/crypto/crc32-arm64.c

使用CRC32指令集需要在编译参数加入-mcpu=generic+crc

#define CRC32X(crc, value) __asm__("crc32x %w[c], %w[c], %x[v]":[c]"+r"(crc):[v]"r"(value))
#define CRC32W(crc, value) __asm__("crc32w %w[c], %w[c], %w[v]":[c]"+r"(crc):[v]"r"(value))
#define CRC32H(crc, value) __asm__("crc32h %w[c], %w[c], %w[v]":[c]"+r"(crc):[v]"r"(value))
#define CRC32B(crc, value) __asm__("crc32b %w[c], %w[c], %w[v]":[c]"+r"(crc):[v]"r"(value))
#define CRC32CX(crc, value) __asm__("crc32cx %w[c], %w[c], %x[v]":[c]"+r"(crc):[v]"r"(value))
#define CRC32CW(crc, value) __asm__("crc32cw %w[c], %w[c], %w[v]":[c]"+r"(crc):[v]"r"(value))
#define CRC32CH(crc, value) __asm__("crc32ch %w[c], %w[c], %w[v]":[c]"+r"(crc):[v]"r"(value))
#define CRC32CB(crc, value) __asm__("crc32cb %w[c], %w[c], %w[v]":[c]"+r"(crc):[v]"r"(value))

uint32_t crc32_arm64_le_hw(uint32_t crc, const uint8_t *p, unsigned int len)
{
	int64_t length = len;

	while ((length -= sizeof(uint64_t)) >= 0) {
		CRC32X(crc, *((uint64_t *)p));
		p += sizeof(uint64_t);
	}

	if (length & sizeof(uint32_t)) {
		CRC32W(crc, *((uint32_t *)p));
		p += sizeof(uint32_t);
	}
	if (length & sizeof(uint16_t)) {
		CRC32H(crc, *((uint16_t *)p));
		p += sizeof(uint16_t);
	}
	if (length & sizeof(uint8_t))
		CRC32B(crc, *p);

	return crc;
}

uint32_t crc32c_arm64_le_hw(uint32_t crc, const uint8_t *p, unsigned int len)
{
	int64_t length = len;

	while ((length -= sizeof(uint64_t)) >= 0) {
		CRC32CX(crc, *((uint64_t *)p));
		p += sizeof(uint64_t);
	}

	if (length & sizeof(uint32_t)) {
		CRC32CW(crc, *((uint32_t *)p));
		p += sizeof(uint32_t);
	}
	if (length & sizeof(uint16_t)) {
		CRC32CH(crc, *((uint16_t *)p));
		p += sizeof(uint16_t);
	}
	if (length & sizeof(uint8_t))
		CRC32CB(crc, *p);

	return crc;
}

发表评论

电子邮件地址不会被公开。 必填项已用*标注