Commit f623e994 authored by Giuseppe Ottaviano's avatar Giuseppe Ottaviano Committed by Facebook GitHub Bot

Use small_vector::copyInlineTrivial only if the storage is small

Reviewed By: Liang-Dong

Differential Revision: D29784019

fbshipit-source-id: f7516603bc73b33ad7c57da1103451f75f8566b4
parent ef028e3b
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
#include <folly/ScopeGuard.h> #include <folly/ScopeGuard.h>
#include <folly/Traits.h> #include <folly/Traits.h>
#include <folly/functional/Invoke.h> #include <folly/functional/Invoke.h>
#include <folly/lang/Align.h>
#include <folly/lang/Assume.h> #include <folly/lang/Assume.h>
#include <folly/lang/Exception.h> #include <folly/lang/Exception.h>
#include <folly/memory/Malloc.h> #include <folly/memory/Malloc.h>
...@@ -506,7 +507,7 @@ class small_vector : public detail::small_vector_base< ...@@ -506,7 +507,7 @@ class small_vector : public detail::small_vector_base<
small_vector(const std::allocator<Value>&) {} small_vector(const std::allocator<Value>&) {}
small_vector(small_vector const& o) { small_vector(small_vector const& o) {
if (folly::is_trivially_copyable<Value>::value && !o.isExtern()) { if (kShouldCopyInlineTrivial && !o.isExtern()) {
copyInlineTrivial<Value>(o); copyInlineTrivial<Value>(o);
return; return;
} }
...@@ -530,7 +531,7 @@ class small_vector : public detail::small_vector_base< ...@@ -530,7 +531,7 @@ class small_vector : public detail::small_vector_base<
this->u.setCapacity(o.u.getCapacity()); this->u.setCapacity(o.u.getCapacity());
} }
} else { } else {
if (folly::is_trivially_copyable<Value>::value) { if (kShouldCopyInlineTrivial) {
copyInlineTrivial<Value>(o); copyInlineTrivial<Value>(o);
o.resetSizePolicy(); o.resetSizePolicy();
} else { } else {
...@@ -574,8 +575,7 @@ class small_vector : public detail::small_vector_base< ...@@ -574,8 +575,7 @@ class small_vector : public detail::small_vector_base<
small_vector& operator=(small_vector const& o) { small_vector& operator=(small_vector const& o) {
if (FOLLY_LIKELY(this != &o)) { if (FOLLY_LIKELY(this != &o)) {
if (folly::is_trivially_copyable<Value>::value && !this->isExtern() && if (kShouldCopyInlineTrivial && !this->isExtern() && !o.isExtern()) {
!o.isExtern()) {
copyInlineTrivial<Value>(o); copyInlineTrivial<Value>(o);
} else if (o.size() < capacity()) { } else if (o.size() < capacity()) {
const size_t oSize = o.size(); const size_t oSize = o.size();
...@@ -598,7 +598,7 @@ class small_vector : public detail::small_vector_base< ...@@ -598,7 +598,7 @@ class small_vector : public detail::small_vector_base<
} }
if (!o.isExtern()) { if (!o.isExtern()) {
if (folly::is_trivially_copyable<Value>::value) { if (kShouldCopyInlineTrivial) {
copyInlineTrivial<Value>(o); copyInlineTrivial<Value>(o);
o.resetSizePolicy(); o.resetSizePolicy();
} else { } else {
...@@ -1031,8 +1031,8 @@ class small_vector : public detail::small_vector_base< ...@@ -1031,8 +1031,8 @@ class small_vector : public detail::small_vector_base<
template <class T> template <class T>
typename std::enable_if<folly::is_trivially_copyable<T>::value>::type typename std::enable_if<folly::is_trivially_copyable<T>::value>::type
copyInlineTrivial(small_vector const& o) { copyInlineTrivial(small_vector const& o) {
// Copy the entire inline storage, instead of just the size, to make the // Copy the entire inline storage, instead of just size() values, to make
// loop fixed-size and unrollable. // the loop fixed-size and unrollable.
std::copy(o.u.buffer(), o.u.buffer() + MaxInline, u.buffer()); std::copy(o.u.buffer(), o.u.buffer() + MaxInline, u.buffer());
this->setSize(o.size()); this->setSize(o.size());
} }
...@@ -1280,6 +1280,13 @@ class small_vector : public detail::small_vector_base< ...@@ -1280,6 +1280,13 @@ class small_vector : public detail::small_vector_base<
InlineStorageDataType, InlineStorageDataType,
value_type*>::type InlineStorageType; value_type*>::type InlineStorageType;
// If the values are trivially copyable and the storage is small enough, copy
// it entirely. Limit is half of a cache line, to minimize probability of
// introducing a cache miss.
static constexpr bool kShouldCopyInlineTrivial =
folly::is_trivially_copyable<Value>::value &&
sizeof(InlineStorageType) <= hardware_constructive_interference_size / 2;
static bool constexpr kHasInlineCapacity = static bool constexpr kHasInlineCapacity =
sizeof(HeapPtrWithCapacity) < sizeof(InlineStorageType); sizeof(HeapPtrWithCapacity) < sizeof(InlineStorageType);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment