fix isal crc64 bug
This commit is contained in:
40
deps/oblib/src/lib/checksum/ob_crc64.cpp
vendored
40
deps/oblib/src/lib/checksum/ob_crc64.cpp
vendored
@ -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;
|
||||||
asm("cpuid": "=a"(a), "=b"(b), "=c"(c), "=d"(d) : "0"(1));
|
|
||||||
if ((c & (1 << 20)) != 0) {
|
uint32_t vendor_info[4];
|
||||||
ob_crc64_sse42_func = &crc64_sse42;
|
__asm__("mov $0x0, %eax\n\t");
|
||||||
_OB_LOG(INFO, "Use CPU crc32 instructs for crc64 calculate");
|
__asm__("cpuid\n\t");
|
||||||
} else {
|
__asm__("mov %%ebx, %0\n\t":"=r" (vendor_info[0]));
|
||||||
ob_crc64_sse42_func = &fast_crc64_sse42_manually;
|
__asm__("mov %%edx, %0\n\t":"=r" (vendor_info[1]));
|
||||||
_OB_LOG(INFO, "Use manual crc32 table lookup for crc64 calculate");
|
__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__)
|
#elif defined(__aarch64__)
|
||||||
#if 1
|
#if 1
|
||||||
|
|||||||
2
deps/oblib/src/lib/checksum/ob_crc64.h
vendored
2
deps/oblib/src/lib/checksum/ob_crc64.h
vendored
@ -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);
|
||||||
|
|
||||||
|
|||||||
19
deps/oblib/unittest/lib/checksum/test_crc64.cpp
vendored
19
deps/oblib/unittest/lib/checksum/test_crc64.cpp
vendored
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user