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)
|
add_definitions(/DHAVE_PTHREAD_CANCEL)
|
||||||
endif()
|
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})
|
add_executable(${CMAKE_PROJECT_NAME} ${HEADERS} ${SOURCES})
|
||||||
|
|
||||||
if (STATIC_BINARY)
|
if (STATIC_BINARY)
|
||||||
|
|
|
@ -562,19 +562,18 @@ enum HashMaxValue : uint64_t {
|
||||||
value = hash_uncompress(std::numeric_limits<uint16_t>::max())
|
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) {
|
if (h <= HashValue::mask) {
|
||||||
h = HashMaxValue::value;
|
return static_cast<uint16_t>(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t shift = 0;
|
if (h >= HashMaxValue::value) {
|
||||||
while (h > HashValue::mask) {
|
return std::numeric_limits<uint16_t>::max();
|
||||||
h >>= 1;
|
|
||||||
shift += (1 << HashValue::bits);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
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
|
} // 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();
|
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 p2pool
|
||||||
|
|
||||||
namespace robin_hood {
|
namespace robin_hood {
|
||||||
|
|
|
@ -74,7 +74,7 @@ set(SOURCES
|
||||||
src/keccak_tests.cpp
|
src/keccak_tests.cpp
|
||||||
src/main.cpp
|
src/main.cpp
|
||||||
src/pool_block_tests.cpp
|
src/pool_block_tests.cpp
|
||||||
src/varint_tests.cpp
|
src/util_tests.cpp
|
||||||
src/wallet_tests.cpp
|
src/wallet_tests.cpp
|
||||||
../external/src/cryptonote/crypto-ops-data.c
|
../external/src/cryptonote/crypto-ops-data.c
|
||||||
../external/src/cryptonote/crypto-ops.c
|
../external/src/cryptonote/crypto-ops.c
|
||||||
|
@ -160,6 +160,19 @@ endif()
|
||||||
|
|
||||||
add_definitions(/DZMQ_STATIC /DP2POOL_LOG_DISABLE)
|
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})
|
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})
|
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}>)
|
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 {
|
namespace p2pool {
|
||||||
|
|
||||||
TEST(varint, read_write)
|
TEST(util, varint)
|
||||||
{
|
{
|
||||||
std::vector<uint8_t> v;
|
std::vector<uint8_t> v;
|
||||||
v.reserve(16);
|
v.reserve(16);
|
||||||
|
@ -82,4 +82,12 @@ TEST(varint, read_write)
|
||||||
ASSERT_EQ(readVarint(buf2, buf2 + 1, check), nullptr);
|
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