Skip to content

Commit

Permalink
Discourage inlining the resize case, as that should happen rather rar…
Browse files Browse the repository at this point in the history
…ely.

If you additionally reuse buffers, this will increase the performance
further.

The metrics based on some internal benchmarks show a speedup of about 1%:

bitsery <dont inline bad cases>
  BigString: 222092ns
  ComplexLittleObjects: 34115ns
  ComplexLittleObjectsBig: 6222801ns

bitsery <original>
  BigString: 242853ns
  ComplexLittleObjects: 35738ns
  ComplexLittleObjectsBig: 6334747ns

The assembly has been checked to be correct: https://godbolt.org/z/Wr7qvfGrK

Additionally, when allocating code, we can tell the compiler that we are
not resizing to a lower size, this saves on gcc 14 a few instructions.
The improvement should be negligible.
  • Loading branch information
Destroyerrrocket authored and fraillt committed Jul 21, 2024
1 parent cd73aca commit be2f295
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 10 deletions.
19 changes: 13 additions & 6 deletions include/bitsery/adapter/buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -269,12 +269,11 @@ class OutputBufferAdapter

void maybeResize(size_t newOffset, std::true_type)
{
if (newOffset > _bufferSize) {
traits::BufferAdapterTraits<Buffer>::increaseBufferSize(
*_buffer, _currOffset, newOffset);
_beginIt = std::begin(*_buffer);
_bufferSize = traits::ContainerTraits<Buffer>::size(*_buffer);
}
if (newOffset > _bufferSize)
BITSERY_UNLIKELY
{
doResize(newOffset);
}
}

void maybeResize(BITSERY_MAYBE_UNUSED size_t newOffset, std::false_type)
Expand All @@ -289,6 +288,14 @@ class OutputBufferAdapter
std::copy_n(data, size, _beginIt + static_cast<diff_t>(_currOffset));
_currOffset = newOffset;
}

BITSERY_NOINLINE void doResize(size_t newOffset)
{
traits::BufferAdapterTraits<Buffer>::increaseBufferSize(
*_buffer, _currOffset, newOffset);
_beginIt = std::begin(*_buffer);
_bufferSize = traits::ContainerTraits<Buffer>::size(*_buffer);
}
};

}
Expand Down
65 changes: 63 additions & 2 deletions include/bitsery/bitsery.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,73 @@
BITSERY_BUILD_VERSION_STR( \
BITSERY_MAJOR_VERSION, BITSERY_MINOR_VERSION, BITSERY_PATCH_VERSION)

#if __cplusplus > 201402L
#define BITSERY_MAYBE_UNUSED [[maybe_unused]]
#define BITSERY_DO_PRAGMA(x) _Pragma(#x)
#ifdef __GNUC__
#define BITSERY_DISABLE_WARNINGS(...) \
BITSERY_DO_PRAGMA(GCC diagnostic push) \
BITSERY_DO_PRAGMA(GCC diagnostic ignored __VA_ARGS__)
#define BITSERY_ENABLE_WARNINGS() BITSERY_DO_PRAGMA(GCC diagnostic pop)
#elif defined(_MSC_VER)
#define BITSERY_DISABLE_WARNINGS(...) \
BITSERY_DO_PRAGMA(GCC diagnostic push) \
BITSERY_DO_PRAGMA(GCC diagnostic ignored __VA_ARGS__) \
BITSERY_DO_PRAGMA(GCC diagnostic pop)
#define BITSERY_ENABLE_WARNINGS() BITSERY_DO_PRAGMA(GCC diagnostic pop)
#else
#define BITSERY_DISABLE_WARNINGS(...)
#define BITSERY_ENABLE_WARNINGS()
#endif

#ifdef __clang__
#define BITSERY_ATTRIBUTE(...) \
BITSERY_DISABLE_WARNINGS("-Wfuture-attribute-extensions") \
[[__VA_ARGS__]] BITSERY_ENABLE_WARNINGS()
#elif defined(__GNUC__)
#define BITSERY_ATTRIBUTE(...) [[__VA_ARGS__]]
#elif defined(_MSC_VER)
#define BITSERY_ATTRIBUTE(...) [[__VA_ARGS__]]
#else
#define BITSERY_ATTRIBUTE(...) [[__VA_ARGS__]]
#endif

#if __has_cpp_attribute(likely)
#define BITSERY_LIKELY BITSERY_ATTRIBUTE(likey)
#else
#define BITSERY_LIKELY
#endif

#if __has_cpp_attribute(unlikely)
#define BITSERY_UNLIKELY BITSERY_ATTRIBUTE(unlikely)
#else
#define BITSERY_UNLIKELY
#endif

#if __has_cpp_attribute(maybe_unused)
#define BITSERY_MAYBE_UNUSED BITSERY_ATTRIBUTE(maybe_unused)
#else
#define BITSERY_MAYBE_UNUSED
#endif

#if __GNUC__
#define BITSERY_NOINLINE __attribute__((noinline))
#elif defined(_MSC_VER)
#define BITSERY_NOINLINE __declspec(noinline)
#else
#define BITSERY_NOINLINE
#endif

#if __GNUC__
#define BITSERY_ASSUME(cond) \
do { \
if (!(cond)) \
__builtin_unreachable(); \
} while (0)
#elif defined(_MSC_VER)
#define BITSERY_ASSUME(cond) __assume(cond)
#else
#define BITSERY_ASSUME(cond)
#endif

#include "deserializer.h"
#include "serializer.h"

Expand Down
8 changes: 6 additions & 2 deletions include/bitsery/traits/core/std_defaults.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#ifndef BITSERY_TRAITS_CORE_STD_DEFAULTS_H
#define BITSERY_TRAITS_CORE_STD_DEFAULTS_H

#include "../../bitsery.h"
#include "../../details/serialization_common.h"
#include "traits.h"

Expand Down Expand Up @@ -103,8 +104,11 @@ struct StdContainerForBufferAdapter<T, true>
static_cast<size_t>(static_cast<double>(container.size()) * 1.5) + 128;
// make data cache friendly
newSize -= newSize % 64; // 64 is cache line size
container.resize(
(std::max)(newSize > minSize ? newSize : minSize, container.capacity()));
auto resize =
(std::max)(newSize > minSize ? newSize : minSize, container.capacity());
BITSERY_ASSUME(resize >= container.size());
BITSERY_ASSUME(resize >= container.capacity());
container.resize(resize);
}
};

Expand Down

0 comments on commit be2f295

Please sign in to comment.