deduplicate code implementing log2p1()
This commit is contained in:
parent
20cb26fcc1
commit
3a4a7b742a
|
@ -37,7 +37,8 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/aux_/export.hpp"
|
#include "libtorrent/aux_/export.hpp"
|
||||||
#include "libtorrent/span.hpp"
|
#include "libtorrent/span.hpp"
|
||||||
|
|
||||||
namespace libtorrent { namespace aux {
|
namespace libtorrent {
|
||||||
|
namespace aux {
|
||||||
|
|
||||||
// For a general reference of the problems these routines are about
|
// For a general reference of the problems these routines are about
|
||||||
// see http://en.wikipedia.org/wiki/Find_first_set
|
// see http://en.wikipedia.org/wiki/Find_first_set
|
||||||
|
@ -61,6 +62,9 @@ namespace libtorrent { namespace aux {
|
||||||
// this function statically determines if hardware or software is used
|
// this function statically determines if hardware or software is used
|
||||||
// and expect the range to be in big-endian byte order
|
// and expect the range to be in big-endian byte order
|
||||||
TORRENT_EXTRA_EXPORT int count_trailing_ones(span<std::uint32_t const> buf);
|
TORRENT_EXTRA_EXPORT int count_trailing_ones(span<std::uint32_t const> buf);
|
||||||
|
|
||||||
|
// returns the index of the most significant set bit.
|
||||||
|
TORRENT_EXTRA_EXPORT int log2p1(std::uint32_t v);
|
||||||
}}
|
}}
|
||||||
|
|
||||||
#endif // TORRENT_FFS_HPP_INCLUDE
|
#endif // TORRENT_FFS_HPP_INCLUDE
|
||||||
|
|
37
src/ffs.cpp
37
src/ffs.cpp
|
@ -42,22 +42,14 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "libtorrent/aux_/disable_warnings_pop.hpp"
|
#include "libtorrent/aux_/disable_warnings_pop.hpp"
|
||||||
|
|
||||||
namespace libtorrent { namespace aux {
|
namespace libtorrent {
|
||||||
|
namespace aux {
|
||||||
|
|
||||||
int count_leading_zeros_sw(span<std::uint32_t const> buf)
|
// returns the index of the first set bit.
|
||||||
|
// Use std::log2p1 in C++20
|
||||||
|
int log2p1(std::uint32_t v)
|
||||||
{
|
{
|
||||||
auto const num = int(buf.size());
|
// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogDeBruijn
|
||||||
std::uint32_t const* ptr = buf.data();
|
|
||||||
|
|
||||||
TORRENT_ASSERT(num >= 0);
|
|
||||||
TORRENT_ASSERT(ptr != nullptr);
|
|
||||||
|
|
||||||
for (int i = 0; i < num; i++)
|
|
||||||
{
|
|
||||||
if (ptr[i] == 0) continue;
|
|
||||||
std::uint32_t v = aux::network_to_host(ptr[i]);
|
|
||||||
|
|
||||||
// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious
|
|
||||||
static const int MultiplyDeBruijnBitPosition[32] =
|
static const int MultiplyDeBruijnBitPosition[32] =
|
||||||
{
|
{
|
||||||
0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
|
0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
|
||||||
|
@ -70,8 +62,21 @@ namespace libtorrent { namespace aux {
|
||||||
v |= v >> 8;
|
v |= v >> 8;
|
||||||
v |= v >> 16;
|
v |= v >> 16;
|
||||||
|
|
||||||
return i * 32 + 31 - MultiplyDeBruijnBitPosition[
|
return MultiplyDeBruijnBitPosition[std::uint32_t(v * 0x07C4ACDDU) >> 27];
|
||||||
static_cast<std::uint32_t>(v * 0x07C4ACDDU) >> 27];
|
}
|
||||||
|
|
||||||
|
int count_leading_zeros_sw(span<std::uint32_t const> buf)
|
||||||
|
{
|
||||||
|
auto const num = int(buf.size());
|
||||||
|
std::uint32_t const* ptr = buf.data();
|
||||||
|
|
||||||
|
TORRENT_ASSERT(num >= 0);
|
||||||
|
TORRENT_ASSERT(ptr != nullptr);
|
||||||
|
|
||||||
|
for (int i = 0; i < num; i++)
|
||||||
|
{
|
||||||
|
if (ptr[i] == 0) continue;
|
||||||
|
return i * 32 + 31 - log2p1(aux::network_to_host(ptr[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
return num * 32;
|
return num * 32;
|
||||||
|
|
|
@ -90,6 +90,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/aux_/scope_end.hpp"
|
#include "libtorrent/aux_/scope_end.hpp"
|
||||||
#include "libtorrent/aux_/set_socket_buffer.hpp"
|
#include "libtorrent/aux_/set_socket_buffer.hpp"
|
||||||
#include "libtorrent/aux_/generate_peer_id.hpp"
|
#include "libtorrent/aux_/generate_peer_id.hpp"
|
||||||
|
#include "libtorrent/aux_/ffs.hpp"
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_LOGGING
|
#ifndef TORRENT_DISABLE_LOGGING
|
||||||
|
|
||||||
|
@ -3510,37 +3511,15 @@ namespace aux {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
|
||||||
// returns the index of the first set bit.
|
|
||||||
int log2(std::uint32_t v)
|
|
||||||
{
|
|
||||||
// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogDeBruijn
|
|
||||||
static const int MultiplyDeBruijnBitPosition[32] =
|
|
||||||
{
|
|
||||||
0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
|
|
||||||
8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
|
|
||||||
};
|
|
||||||
|
|
||||||
v |= v >> 1; // first round down to one less than a power of 2
|
|
||||||
v |= v >> 2;
|
|
||||||
v |= v >> 4;
|
|
||||||
v |= v >> 8;
|
|
||||||
v |= v >> 16;
|
|
||||||
|
|
||||||
return MultiplyDeBruijnBitPosition[std::uint32_t(v * 0x07C4ACDDU) >> 27];
|
|
||||||
}
|
|
||||||
|
|
||||||
} // anonymous namespace
|
|
||||||
|
|
||||||
void session_impl::received_buffer(int s)
|
void session_impl::received_buffer(int s)
|
||||||
{
|
{
|
||||||
int index = std::min(log2(std::uint32_t(s >> 3)), 17);
|
int index = std::min(aux::log2p1(std::uint32_t(s >> 3)), 17);
|
||||||
m_stats_counters.inc_stats_counter(counters::socket_recv_size3 + index);
|
m_stats_counters.inc_stats_counter(counters::socket_recv_size3 + index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void session_impl::sent_buffer(int s)
|
void session_impl::sent_buffer(int s)
|
||||||
{
|
{
|
||||||
int index = std::min(log2(std::uint32_t(s >> 3)), 17);
|
int index = std::min(aux::log2p1(std::uint32_t(s >> 3)), 17);
|
||||||
m_stats_counters.inc_stats_counter(counters::socket_send_size3 + index);
|
m_stats_counters.inc_stats_counter(counters::socket_send_size3 + index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue