mirror of
https://github.com/SChernykh/p2pool.git
synced 2024-12-22 19:39:22 +00:00
Added bsr() function to util
This commit is contained in:
parent
820c5db5e8
commit
d23c46ff84
6 changed files with 98 additions and 10 deletions
|
@ -142,6 +142,19 @@ if (HAVE_PTHREAD_CANCEL)
|
|||
add_definitions(/DHAVE_PTHREAD_CANCEL)
|
||||
endif()
|
||||
|
||||
include(CheckCXXSourceCompiles)
|
||||
|
||||
check_cxx_source_compiles("int main(){ return __builtin_clzll(1);}" HAVE_BUILTIN_CLZLL)
|
||||
check_cxx_source_compiles("#include <intrin.h>\n#pragma intrinsic(_BitScanReverse64)\nint main(){unsigned long r;_BitScanReverse64(&r,1);return r;}" HAVE_BITSCANREVERSE64)
|
||||
|
||||
if (HAVE_BUILTIN_CLZLL)
|
||||
add_definitions(/DHAVE_BUILTIN_CLZLL)
|
||||
endif()
|
||||
|
||||
if (HAVE_BITSCANREVERSE64)
|
||||
add_definitions(/DHAVE_BITSCANREVERSE64)
|
||||
endif()
|
||||
|
||||
add_executable(${CMAKE_PROJECT_NAME} ${HEADERS} ${SOURCES})
|
||||
|
||||
if (STATIC_BINARY)
|
||||
|
|
|
@ -562,19 +562,18 @@ enum HashMaxValue : uint64_t {
|
|||
value = hash_uncompress(std::numeric_limits<uint16_t>::max())
|
||||
};
|
||||
|
||||
static constexpr FORCEINLINE uint16_t hash_compress(uint64_t h)
|
||||
static FORCEINLINE uint16_t hash_compress(uint64_t h)
|
||||
{
|
||||
if (h > HashMaxValue::value) {
|
||||
h = HashMaxValue::value;
|
||||
if (h <= HashValue::mask) {
|
||||
return static_cast<uint16_t>(h);
|
||||
}
|
||||
|
||||
uint64_t shift = 0;
|
||||
while (h > HashValue::mask) {
|
||||
h >>= 1;
|
||||
shift += (1 << HashValue::bits);
|
||||
if (h >= HashMaxValue::value) {
|
||||
return std::numeric_limits<uint16_t>::max();
|
||||
}
|
||||
|
||||
return static_cast<uint16_t>(shift | h);
|
||||
const uint64_t shift = bsr(h) - (HashValue::bits - 1);
|
||||
return static_cast<uint16_t>((shift << HashValue::bits) | (h >> shift));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
39
src/util.cpp
39
src/util.cpp
|
@ -384,4 +384,43 @@ bool resolve_host(std::string& host, bool& is_v6)
|
|||
|
||||
RandomDeviceSeed RandomDeviceSeed::instance;
|
||||
|
||||
struct BSR8
|
||||
{
|
||||
uint8_t data[256];
|
||||
|
||||
static constexpr BSR8 init() {
|
||||
BSR8 result = { 55 };
|
||||
|
||||
for (int i = 1; i < 256; ++i) {
|
||||
int x = i;
|
||||
result.data[i] = 63;
|
||||
while (x < 0x80) {
|
||||
--result.data[i];
|
||||
x <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
static constexpr BSR8 bsr8_table = BSR8::init();
|
||||
|
||||
NOINLINE uint64_t bsr_reference(uint64_t x)
|
||||
{
|
||||
uint32_t y = static_cast<uint32_t>(x);
|
||||
|
||||
uint64_t n0 = (x == y) ? 0 : 32;
|
||||
y = static_cast<uint32_t>(x >> n0);
|
||||
n0 ^= 32;
|
||||
|
||||
const uint64_t n1 = (y & 0xFFFF0000UL) ? 0 : 16;
|
||||
y <<= n1;
|
||||
|
||||
const uint64_t n2 = (y & 0xFF000000UL) ? 0 : 8;
|
||||
y <<= n2;
|
||||
|
||||
return bsr8_table.data[y >> 24] - n0 - n1 - n2;
|
||||
}
|
||||
|
||||
} // namespace p2pool
|
||||
|
|
16
src/util.h
16
src/util.h
|
@ -203,6 +203,22 @@ FORCEINLINE uint64_t seconds_since_epoch()
|
|||
return duration_cast<seconds>(steady_clock::now().time_since_epoch()).count();
|
||||
}
|
||||
|
||||
uint64_t bsr_reference(uint64_t x);
|
||||
|
||||
#ifdef HAVE_BUILTIN_CLZLL
|
||||
#define bsr(x) (63 - __builtin_clzll(x))
|
||||
#elif defined HAVE_BITSCANREVERSE64
|
||||
#pragma intrinsic(_BitScanReverse64)
|
||||
FORCEINLINE uint64_t bsr(uint64_t x)
|
||||
{
|
||||
unsigned long index;
|
||||
_BitScanReverse64(&index, x);
|
||||
return index;
|
||||
}
|
||||
#else
|
||||
#define bsr bsr_reference
|
||||
#endif
|
||||
|
||||
} // namespace p2pool
|
||||
|
||||
namespace robin_hood {
|
||||
|
|
|
@ -74,7 +74,7 @@ set(SOURCES
|
|||
src/keccak_tests.cpp
|
||||
src/main.cpp
|
||||
src/pool_block_tests.cpp
|
||||
src/varint_tests.cpp
|
||||
src/util_tests.cpp
|
||||
src/wallet_tests.cpp
|
||||
../external/src/cryptonote/crypto-ops-data.c
|
||||
../external/src/cryptonote/crypto-ops.c
|
||||
|
@ -160,6 +160,19 @@ endif()
|
|||
|
||||
add_definitions(/DZMQ_STATIC /DP2POOL_LOG_DISABLE)
|
||||
|
||||
include(CheckCXXSourceCompiles)
|
||||
|
||||
check_cxx_source_compiles("int main(){ return __builtin_clzll(1);}" HAVE_BUILTIN_CLZLL)
|
||||
check_cxx_source_compiles("#include <intrin.h>\n#pragma intrinsic(_BitScanReverse64)\nint main(){unsigned long r;_BitScanReverse64(&r,1);return r;}" HAVE_BITSCANREVERSE64)
|
||||
|
||||
if (HAVE_BUILTIN_CLZLL)
|
||||
add_definitions(/DHAVE_BUILTIN_CLZLL)
|
||||
endif()
|
||||
|
||||
if (HAVE_BITSCANREVERSE64)
|
||||
add_definitions(/DHAVE_BITSCANREVERSE64)
|
||||
endif()
|
||||
|
||||
add_executable(${CMAKE_PROJECT_NAME} ${HEADERS} ${SOURCES})
|
||||
target_link_libraries(${CMAKE_PROJECT_NAME} debug ${ZMQ_LIBRARY_DEBUG} debug ${UV_LIBRARY_DEBUG} optimized ${ZMQ_LIBRARY} optimized ${UV_LIBRARY} ${LIBS})
|
||||
add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/src/crypto_tests.txt" $<TARGET_FILE_DIR:${CMAKE_PROJECT_NAME}>)
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
namespace p2pool {
|
||||
|
||||
TEST(varint, read_write)
|
||||
TEST(util, varint)
|
||||
{
|
||||
std::vector<uint8_t> v;
|
||||
v.reserve(16);
|
||||
|
@ -82,4 +82,12 @@ TEST(varint, read_write)
|
|||
ASSERT_EQ(readVarint(buf2, buf2 + 1, check), nullptr);
|
||||
}
|
||||
|
||||
TEST(util, bsr)
|
||||
{
|
||||
for (uint64_t i = 0, x = 1; i <= 63; ++i, x <<= 1) {
|
||||
ASSERT_EQ(bsr(x), i);
|
||||
ASSERT_EQ(bsr_reference(x), i);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue