deduplicate code implementing log2p1()

This commit is contained in:
Arvid Norberg 2019-03-23 12:53:36 +01:00 committed by Arvid Norberg
parent 20cb26fcc1
commit 3a4a7b742a
3 changed files with 31 additions and 43 deletions

View File

@ -37,7 +37,8 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/aux_/export.hpp"
#include "libtorrent/span.hpp"
namespace libtorrent { namespace aux {
namespace libtorrent {
namespace aux {
// For a general reference of the problems these routines are about
// 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
// and expect the range to be in big-endian byte order
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

View File

@ -42,7 +42,28 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/aux_/disable_warnings_pop.hpp"
namespace libtorrent { namespace aux {
namespace libtorrent {
namespace aux {
// returns the index of the first set bit.
// Use std::log2p1 in C++20
int log2p1(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];
}
int count_leading_zeros_sw(span<std::uint32_t const> buf)
{
@ -55,23 +76,7 @@ namespace libtorrent { namespace aux {
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] =
{
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 i * 32 + 31 - MultiplyDeBruijnBitPosition[
static_cast<std::uint32_t>(v * 0x07C4ACDDU) >> 27];
return i * 32 + 31 - log2p1(aux::network_to_host(ptr[i]));
}
return num * 32;

View File

@ -90,6 +90,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/aux_/scope_end.hpp"
#include "libtorrent/aux_/set_socket_buffer.hpp"
#include "libtorrent/aux_/generate_peer_id.hpp"
#include "libtorrent/aux_/ffs.hpp"
#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)
{
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);
}
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);
}