fix benchmark error

This commit is contained in:
tqcq 2024-07-12 16:17:00 +08:00 committed by tqcq
parent 9bd627ea6c
commit 52a4e711b5
4 changed files with 249 additions and 18 deletions

View File

@ -0,0 +1,54 @@
#ifndef TILE_BASE_THREAD_THREAD_LOCAL_H
#define TILE_BASE_THREAD_THREAD_LOCAL_H
#pragma once
#include "tile/base/internal/meta.h"
#include "tile/base/thread/mutex.h"
#include "tile/base/thread/scoped_lock.h"
#include <mutex>
namespace tile {
template<typename T>
class ThreadLocal {
public:
ThreadLocal() : ThreadLocal([]() {}) {};
template<typename F, enable_if_t<eggs::is_invocable_r<std::unique_ptr<T>, F>::value> * = nullptr>
explicit ThreadLocal(F &&creator) : creator_(std::forward<F>(creator))
{}
T *Get() const {}
T *operator->() const { return Get(); }
T &operator*() const { return *Get(); }
T *Leak() noexcept
{
ScopedLock _(init_lock_);
return nullptr;
}
void Reset(std::unique_ptr<T> ptr = nullptr) noexcept { ScopedLock _(init_lock_); }
template<typename F>
void ForEach(F &&f) const
{
ScopedLock _(init_lock_);
}
ThreadLocal(const ThreadLocal &) = delete;
ThreadLocal &operator=(const ThreadLocal &) = delete;
private:
static thread_local T val_;
private:
mutable Mutex init_lock_;
std::function<std::unique_ptr<T>()> creator_;
};
}// namespace tile
#endif// TILE_BASE_THREAD_THREAD_LOCAL_H

View File

@ -0,0 +1,148 @@
#ifndef TILE_BASE_THREAD_THREAD_LOCAL_OBJECT_ARRAY_H
#define TILE_BASE_THREAD_THREAD_LOCAL_OBJECT_ARRAY_H
#pragma once
#include "tile/base/align.h"
#include "tile/base/logging.h"
#include "tile/base/thread/mutex.h"
#include "tile/base/thread/scoped_lock.h"
namespace tile {
namespace tls {
namespace detail {
template<typename T>
struct Entry {
std::aligned_storage<sizeof(T), alignof(T)> storage;
static_assert(sizeof(T) == sizeof(storage), "");
};
template<typename T>
struct ObjectArrayCache {
std::size_t limit{};
T *objects{};
};
template<typename T>
struct ObjectArray;
template<typename T>
class LazyInitObjectArray {
struct EntryDeleter {
void operator()(Entry<T> *ptr) noexcept { operator delete(ptr); }
};
using AlignedArray = std::unique_ptr<Entry<T>[], EntryDeleter>;
public:
LazyInitObjectArray() = default;
~LazyInitObjectArray()
{
for (int i = 0; i != initialized_.size(); ++i) {
if (initialized_[i]) { reinterpret_cast<T *>(&objects_[i])->~T(); }
}
}
LazyInitObjectArray(LazyInitObjectArray &&) = default;
LazyInitObjectArray &operator=(LazyInitObjectArray &&) = default;
template<typename F>
void InitializeAt(std::size_t index, F &&f)
{
TILE_CHECK_LT(index, initialized_.size());
TILE_CHECK(!initialized_[index]);
initialized_[index] = true;
std::forward<F>(f)(&objects_[index]);
}
void DestroyAt(std::size_t index)
{
TILE_CHECK_LT(index, initialized_.size());
TILE_CHECK(initialized_[index]);
initialized_[index] = false;
reinterpret_cast<T *>(&objects_[index])->~T();
}
bool IsInitializedAt(std::size_t index) const noexcept
{
TILE_CHECK_LT(index, initialized_.size());
return initialized_[index];
}
T *GetAt(std::size_t index) noexcept
{
TILE_CHECK_LT(index, initialized_.size());
TILE_CHECK(initialized_[index]);
return reinterpret_cast<T *>(&objects_[index]);
}
T *GetObjectsMaybeUninitialized() noexcept
{
static_assert(sizeof(T) == sizeof(Entry<T>), "");
return reinterpret_cast<T *>(objects_.get());
}
std::size_t size() const noexcept { return initialized_.size(); }
private:
AlignedArray objects_;
std::vector<bool> initialized_;
};
template<typename T>
class ObjectArrayRegistry {
public:
static ObjectArrayRegistry *Instance()
{
static NeverDestroyedSingleton<ObjectArrayRegistry> instance;
return instance.get();
}
void Register(ObjectArray<T> *array)
{
ScopedLock _(lock_);
TILE_DCHECK(std::find(arrays_.begin(), arrays_.end(), array) == arrays_.end());
arrays_.push_back(array);
}
void Deregister(ObjectArray<T> *array)
{
ScopedLock _(lock_);
auto iter = std::find(arrays_.begin(), arrays_.end(), array);
TILE_CHECK(iter != arrays_.end());
arrays_.erase(iter);
}
template<typename F>
void ForEachLocked(std::size_t index, F &&f)
{
ScopedLock _(lock_);
for (auto &&e : arrays_) {
ScopedLock _(e->lock);
if (index < e->objects.size()) { f(e); }
}
}
private:
Mutex lock_;
std::vector<ObjectArray<T> *> arrays_;
};
template<typename T>
struct ObjectArray {
Mutex lock;
LazyInitObjectArray<T> objects_;
ObjectArray() { ObjectArrayRegistry<T>::Instance()->Register(this); }
~ObjectArray() { ObjectArrayRegistry<T>::Instance()->Deregister(this); }
};
}// namespace detail
}// namespace tls
}// namespace tile
#endif// TILE_BASE_THREAD_THREAD_LOCAL_OBJECT_ARRAY_H

View File

@ -11,22 +11,24 @@ namespace tile {
namespace testing { namespace testing {
namespace { namespace {
int StartBenchmark(int argc, char **argv) { int
StartBenchmark(int argc, char **argv)
{
::benchmark::Initialize(&argc, argv); ::benchmark::Initialize(&argc, argv);
if (::benchmark::ReportUnrecognizedArguments(argc, argv)) { if (::benchmark::ReportUnrecognizedArguments(argc, argv)) { return 1; }
return 1;
}
::benchmark::RunSpecifiedBenchmarks(); ::benchmark::RunSpecifiedBenchmarks();
::benchmark::Shutdown(); ::benchmark::Shutdown();
return 0; return 0;
} }
}// namespace }// namespace
int InitAndRunAllBenchmarks(int *argc, char **argv) { int
InitAndRunAllBenchmarks(int *argc, char **argv)
{
if (gflags::GetCommandLineFlagInfoOrDie("logtostderr").is_default) { // if (gflags::GetCommandLineFlagInfoOrDie("logtostderr").is_default) {
FLAGS_logtostderr = true; // FLAGS_logtostderr = true;
} // }
return Start(*argc, argv, StartBenchmark, true); return Start(*argc, argv, StartBenchmark, true);
} }

View File

@ -4,18 +4,45 @@
#pragma once #pragma once
// base module // base module
#include "tile/base/defered.h" #include "tile/base/align.h"
#include "tile/base/buffer.h"
#include "tile/base/casting.h"
#include "tile/base/chrono.h"
#include "tile/base/compression.h"
#include "tile/base/data.h"
#include "tile/base/deferred.h"
#include "tile/base/demangle.h"
#include "tile/base/dependency_registry.h"
#include "tile/base/down_cast.h" #include "tile/base/down_cast.h"
#include "tile/base/encoding.h" #include "tile/base/encoding.h"
#include "tile/base/enum.h"
#include "tile/base/erased_ptr.h"
#include "tile/base/exposed_var.h"
#include "tile/base/future.h"
#include "tile/base/handle.h"
#include "tile/base/id_alloc.h"
#include "tile/base/likely.h"
#include "tile/base/logging.h" #include "tile/base/logging.h"
#include "tile/base/make_unique.h"
#include "tile/base/maybe_owning.h"
#include "tile/base/never_destroyed.h"
#include "tile/base/object_pool.h"
#include "tile/base/option.h"
#include "tile/base/optional.h" #include "tile/base/optional.h"
#include "tile/base/random.h" #include "tile/base/random.h"
#include "tile/base/ref_ptr.h"
#include "tile/base/slice.h" #include "tile/base/slice.h"
#include "tile/base/status.h"
#include "tile/base/string.h" #include "tile/base/string.h"
#include "tile/base/type_index.h"
#include "tile/base/variant.h"
#include "tile/base/write_mostly.h"
// init module // init module
#include "tile/init/override_flag.h" #include "tile/init/override_flag.h"
#include "sigslot/signal.h"
// Tile Init // Tile Init
#include "tile/init.h" #include "tile/init.h"