fix isal crc64 bug

This commit is contained in:
hnwyllmm
2022-11-02 22:38:15 +00:00
committed by wangzelin.wzl
parent 0a044c272d
commit be0b714b75
3 changed files with 49 additions and 12 deletions

View File

@ -13,6 +13,8 @@
#include <stdlib.h> #include <stdlib.h>
#include "lib/checksum/ob_crc64.h" #include "lib/checksum/ob_crc64.h"
#include "lib/ob_define.h" #include "lib/ob_define.h"
#include "isa-l/crc64.h"
#include "isa-l/crc.h"
namespace oceanbase namespace oceanbase
{ {
@ -420,7 +422,7 @@ for RHEL4 support (GCC 3 doesn't support this instruction) */
#define crc32_sse42_byte crc = __crc32cb(crc, (uint8_t)*buf); len--, buf++ #define crc32_sse42_byte crc = __crc32cb(crc, (uint8_t)*buf); len--, buf++
#endif /* defined(__GNUC__) && defined(__x86_64__) */ #endif /* defined(__GNUC__) && defined(__x86_64__) */
inline static uint64_t crc64_sse42(uint64_t uCRC64, uint64_t crc64_sse42(uint64_t uCRC64,
const char *buf, int64_t len) const char *buf, int64_t len)
{ {
uint64_t crc = uCRC64; uint64_t crc = uCRC64;
@ -1102,6 +1104,14 @@ uint64_t fast_crc64_sse42_manually(uint64_t crc, const char *buf, int64_t len)
return crc; return crc;
} }
//If the CPU is intel, ISA-L library for CRC can be used
uint64_t ob_crc64_isal(uint64_t uCRC64, const char* buf, int64_t cb)
{
if (buf == NULL || cb <= 0){
return uCRC64;
}
return crc32_iscsi((unsigned char*)(buf), cb, uCRC64);
}
uint64_t crc64_sse42_dispatch(uint64_t crc, const char *buf, int64_t len) uint64_t crc64_sse42_dispatch(uint64_t crc, const char *buf, int64_t len)
{ {
@ -1110,13 +1120,27 @@ uint64_t crc64_sse42_dispatch(uint64_t crc, const char *buf, int64_t len)
uint32_t b = 0; uint32_t b = 0;
uint32_t c = 0; uint32_t c = 0;
uint32_t d = 0; uint32_t d = 0;
uint32_t vendor_info[4];
__asm__("mov $0x0, %eax\n\t");
__asm__("cpuid\n\t");
__asm__("mov %%ebx, %0\n\t":"=r" (vendor_info[0]));
__asm__("mov %%edx, %0\n\t":"=r" (vendor_info[1]));
__asm__("mov %%ecx, %0\n\t":"=r" (vendor_info[2]));
vendor_info[3]='\0';
if (strcmp((char*)vendor_info, "GenuineIntel") == 0) {
ob_crc64_sse42_func = &ob_crc64_isal;
_OB_LOG(WARN, "Use ISAL for crc64 calculate");
} else{
asm("cpuid" : "=a"(a), "=b"(b), "=c"(c), "=d"(d) : "0"(1)); asm("cpuid" : "=a"(a), "=b"(b), "=c"(c), "=d"(d) : "0"(1));
if ((c & (1 << 20)) != 0) { if ((c & (1 << 20)) != 0) {
ob_crc64_sse42_func = &crc64_sse42; ob_crc64_sse42_func = &crc64_sse42;
_OB_LOG(INFO, "Use CPU crc32 instructs for crc64 calculate"); _OB_LOG(WARN, "Use CPU crc32 instructs for crc64 calculate");
} else { } else {
ob_crc64_sse42_func = &fast_crc64_sse42_manually; ob_crc64_sse42_func = &fast_crc64_sse42_manually;
_OB_LOG(INFO, "Use manual crc32 table lookup for crc64 calculate"); _OB_LOG(WARN, "Use manual crc32 table lookup for crc64 calculate");
}
} }
#elif defined(__aarch64__) #elif defined(__aarch64__)
#if 1 #if 1

View File

@ -68,6 +68,8 @@ inline uint64_t ob_crc64_sse42(const void *pv, int64_t cb)
return (*ob_crc64_sse42_func)(0, static_cast<const char *>(pv), cb); return (*ob_crc64_sse42_func)(0, static_cast<const char *>(pv), cb);
} }
uint64_t ob_crc64_isal(uint64_t uCRC64, const char* buf, int64_t cb);
uint64_t crc64_sse42(uint64_t uCRC64, const char* buf, int64_t len);
uint64_t crc64_sse42_manually(uint64_t crc, const char *buf, int64_t len); uint64_t crc64_sse42_manually(uint64_t crc, const char *buf, int64_t len);
uint64_t fast_crc64_sse42_manually(uint64_t crc, const char *buf, int64_t len); uint64_t fast_crc64_sse42_manually(uint64_t crc, const char *buf, int64_t len);

View File

@ -41,13 +41,16 @@ TEST(TestCrc64, common)
const int64_t STR_LEN = 10240; const int64_t STR_LEN = 10240;
char *tmp_str = new char[STR_LEN]; char *tmp_str = new char[STR_LEN];
char *str = NULL; char *str = NULL;
uint64_t intermediate_hash = 0;
for (int64_t i = 1; i < (STR_LEN - 1); ++i) { for (int64_t i = 1; i < (STR_LEN - 1); ++i) {
str = rand_str(tmp_str, i); str = rand_str(tmp_str, i);
uint64_t manually_hash = crc64_sse42_manually(0, str, i); uint64_t manually_hash = crc64_sse42_manually(intermediate_hash, str, i);
uint64_t fast_manually_hash = fast_crc64_sse42_manually(0, str, i); uint64_t fast_manually_hash = fast_crc64_sse42_manually(intermediate_hash, str, i);
uint64_t sse42_hash = ob_crc64(0, str, i); uint64_t sse42_hash = crc64_sse42(intermediate_hash, str, i);
uint64_t isal_hash = ob_crc64_isal(intermediate_hash, str, i);
ASSERT_EQ(manually_hash, fast_manually_hash); ASSERT_EQ(manually_hash, fast_manually_hash);
ASSERT_EQ(manually_hash, sse42_hash); ASSERT_EQ(manually_hash, sse42_hash);
ASSERT_EQ(manually_hash, isal_hash);
//cout << "st = "<< tmp_str << endl; //cout << "st = "<< tmp_str << endl;
//cout << "crc64c = "<< manually_hash << endl; //cout << "crc64c = "<< manually_hash << endl;
} }
@ -77,11 +80,19 @@ TEST(TestCrc64, test_speed)
start = get_current_time_us(); start = get_current_time_us();
for (int64_t j = 0; j < COUNT; ++j) { for (int64_t j = 0; j < COUNT; ++j) {
ob_crc64(0, tmp_str, i); crc64_sse42(0, tmp_str, i);
} }
end = get_current_time_us(); end = get_current_time_us();
cout << " ob_crc64(sse42), execut_count = "<< COUNT << ", cost_us = " << end - start << " len = " << i << endl; cout << " ob_crc64(sse42), execut_count = "<< COUNT << ", cost_us = " << end - start << " len = " << i << endl;
start = get_current_time_us();
for (int64_t j = 0; j < COUNT; ++j) {
ob_crc64_isal(0, tmp_str, i);
}
end = get_current_time_us();
cout << " ob_crc64(ob_crc64_isal), execut_count = " << COUNT << ", cost_us = " << end - start << " len = " << i
<< endl;
cout << endl; cout << endl;
cout << endl; cout << endl;
} }