Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move helper functions out of sse4.2 object #5

Merged
merged 3 commits into from
Jul 21, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions port/port_example.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@ extern bool Snappy_Uncompress(const char* input_data, size_t input_length,
// The concatenation of all "data[0,n-1]" fragments is the heap profile.
extern bool GetHeapProfile(void (*func)(void*, const char*, int), void* arg);

// Determine whether a working accelerated crc32 implementation exists
// Returns true if AcceleratedCRC32C is safe to call
bool HasAcceleratedCRC32C();

// Extend the CRC to include the first n bytes of buf.
//
// Returns zero if the CRC cannot be extended using acceleration, else returns
Expand Down
14 changes: 14 additions & 0 deletions port/port_posix.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
#include <stdio.h>
#include <string.h>

#if defined(__GNUC__)
#include <cpuid.h>
#endif

namespace leveldb {
namespace port {

Expand Down Expand Up @@ -49,5 +53,15 @@ void InitOnce(OnceType* once, void (*initializer)()) {
PthreadCall("once", pthread_once(once, initializer));
}

bool HasAcceleratedCRC32C() {
#if (__x86_64__ || __i386__) && defined(__GNUC__)
unsigned int eax, ebx, ecx, edx;
__get_cpuid(1, &eax, &ebx, &ecx, &edx);
return (ecx & (1 << 20)) != 0;
#else
return false;
#endif
}

} // namespace port
} // namespace leveldb
1 change: 1 addition & 0 deletions port/port_posix.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ inline bool GetHeapProfile(void (*func)(void*, const char*, int), void* arg) {
return false;
}

bool HasAcceleratedCRC32C();
uint32_t AcceleratedCRC32C(uint32_t crc, const char* buf, size_t size);

} // namespace port
Expand Down
19 changes: 0 additions & 19 deletions port/port_posix_sse.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
#include <intrin.h>
#elif defined(__GNUC__) && defined(__SSE4_2__)
#include <nmmintrin.h>
#include <cpuid.h>
#endif

#endif // defined(LEVELDB_PLATFORM_POSIX_SSE)
Expand Down Expand Up @@ -48,20 +47,6 @@ static inline uint64_t LE_LOAD64(const uint8_t *p) {

#endif // defined(_M_X64) || defined(__x86_64__)

static inline bool HaveSSE42() {
#if defined(_MSC_VER)
int cpu_info[4];
__cpuid(cpu_info, 1);
return (cpu_info[2] & (1 << 20)) != 0;
#elif defined(__GNUC__)
unsigned int eax, ebx, ecx, edx;
__get_cpuid(1, &eax, &ebx, &ecx, &edx);
return (ecx & (1 << 20)) != 0;
#else
return false;
#endif
}

#endif // defined(LEVELDB_PLATFORM_POSIX_SSE)

// For further improvements see Intel publication at:
Expand All @@ -70,10 +55,6 @@ uint32_t AcceleratedCRC32C(uint32_t crc, const char* buf, size_t size) {
#if !defined(LEVELDB_PLATFORM_POSIX_SSE)
return 0;
#else
static bool have = HaveSSE42();
if (!have) {
return 0;
}

const uint8_t *p = reinterpret_cast<const uint8_t *>(buf);
const uint8_t *e = p + size;
Expand Down
11 changes: 11 additions & 0 deletions port/port_win.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

#include <windows.h>
#include <cassert>
#include <intrin.h>

namespace leveldb {
namespace port {
Expand Down Expand Up @@ -143,5 +144,15 @@ void AtomicPointer::NoBarrier_Store(void* v) {
rep_ = v;
}

bool HasAcceleratedCRC32C() {
#if (__x86_64__ || __i386__)
int cpu_info[4];
__cpuid(cpu_info, 1);
return (cpu_info[2] & (1 << 20)) != 0;
#else
return false;
#endif
}

}
}
1 change: 1 addition & 0 deletions port/port_win.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ inline bool GetHeapProfile(void (*func)(void*, const char*, int), void* arg) {
return false;
}

bool HasAcceleratedCRC32C();
uint32_t AcceleratedCRC32C(uint32_t crc, const char* buf, size_t size);

}
Expand Down
4 changes: 4 additions & 0 deletions util/crc32c.cc
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,10 @@ static inline uint32_t LE_LOAD32(const uint8_t *p) {
// Determine if the CPU running this program can accelerate the CRC32C
// calculation.
static bool CanAccelerateCRC32C() {
if (!port::HasAcceleratedCRC32C())
return false;

// Double-check that the accelerated implementation functions correctly.
// port::AcceleretedCRC32C returns zero when unable to accelerate.
static const char kTestCRCBuffer[] = "TestCRCBuffer";
static const char kBufSize = sizeof(kTestCRCBuffer) - 1;
Expand Down