diff --git a/deps/oblib/src/lib/checksum/ob_crc64.cpp b/deps/oblib/src/lib/checksum/ob_crc64.cpp index bab4b0ee8188a8b971d4459efb81718d84f85d5a..ffdc22bd5920018795fbf2ebf7050aef3e3d1acd 100644 --- a/deps/oblib/src/lib/checksum/ob_crc64.cpp +++ b/deps/oblib/src/lib/checksum/ob_crc64.cpp @@ -13,6 +13,8 @@ #include #include "lib/checksum/ob_crc64.h" #include "lib/ob_define.h" +#include "isa-l/crc64.h" +#include "isa-l/crc.h" 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++ #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) { 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; } +//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) { @@ -1110,13 +1120,27 @@ uint64_t crc64_sse42_dispatch(uint64_t crc, const char *buf, int64_t len) uint32_t b = 0; uint32_t c = 0; uint32_t d = 0; - asm("cpuid": "=a"(a), "=b"(b), "=c"(c), "=d"(d) : "0"(1)); - if ((c & (1 << 20)) != 0) { - ob_crc64_sse42_func = &crc64_sse42; - _OB_LOG(INFO, "Use CPU crc32 instructs for crc64 calculate"); - } else { - ob_crc64_sse42_func = &fast_crc64_sse42_manually; - _OB_LOG(INFO, "Use manual crc32 table lookup for crc64 calculate"); + + 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)); + if ((c & (1 << 20)) != 0) { + ob_crc64_sse42_func = &crc64_sse42; + _OB_LOG(WARN, "Use CPU crc32 instructs for crc64 calculate"); + } else { + ob_crc64_sse42_func = &fast_crc64_sse42_manually; + _OB_LOG(WARN, "Use manual crc32 table lookup for crc64 calculate"); + } } #elif defined(__aarch64__) #if 1 diff --git a/deps/oblib/src/lib/checksum/ob_crc64.h b/deps/oblib/src/lib/checksum/ob_crc64.h index 8794202e9bc10101a2b71485d78b12e579d633ec..d7ce4458a2ff73dde48eff87bb8a05f3bfcd64b4 100644 --- a/deps/oblib/src/lib/checksum/ob_crc64.h +++ b/deps/oblib/src/lib/checksum/ob_crc64.h @@ -68,6 +68,8 @@ inline uint64_t ob_crc64_sse42(const void *pv, int64_t cb) return (*ob_crc64_sse42_func)(0, static_cast(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 fast_crc64_sse42_manually(uint64_t crc, const char *buf, int64_t len); diff --git a/deps/oblib/unittest/lib/checksum/test_crc64.cpp b/deps/oblib/unittest/lib/checksum/test_crc64.cpp index 9a64336722a1334a2c15c5e956c22eee9317ca12..5cd8ccaa4b5918075cf79e595b5ab18891194ebb 100644 --- a/deps/oblib/unittest/lib/checksum/test_crc64.cpp +++ b/deps/oblib/unittest/lib/checksum/test_crc64.cpp @@ -41,13 +41,16 @@ TEST(TestCrc64, common) const int64_t STR_LEN = 10240; char *tmp_str = new char[STR_LEN]; char *str = NULL; + uint64_t intermediate_hash = 0; for (int64_t i = 1; i < (STR_LEN - 1); ++i) { str = rand_str(tmp_str, i); - uint64_t manually_hash = crc64_sse42_manually(0, str, i); - uint64_t fast_manually_hash = fast_crc64_sse42_manually(0, str, i); - uint64_t sse42_hash = ob_crc64(0, str, i); + uint64_t manually_hash = crc64_sse42_manually(intermediate_hash, str, i); + uint64_t fast_manually_hash = fast_crc64_sse42_manually(intermediate_hash, 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, sse42_hash); + ASSERT_EQ(manually_hash, isal_hash); //cout << "st = "<< tmp_str << endl; //cout << "crc64c = "<< manually_hash << endl; } @@ -77,11 +80,19 @@ TEST(TestCrc64, test_speed) start = get_current_time_us(); 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(); 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; }