1#ifndef _FMATVEC_LRUCACHE_H_
2#define _FMATVEC_LRUCACHE_H_
6#include <unordered_map>
8#include <boost/container_hash/hash.hpp>
9#include <fmatvec/fmatvec.h>
10#include <fmatvec/atom.h>
14 template<
class Row,
class AT>
18 for(
int i=0; i<v.size(); ++i)
19 hash_combine(h, v(i));
24 template<
class Col,
class AT>
28 for(
int i=0; i<v.size(); ++i)
29 hash_combine(h, v(i));
34 template<
class Type,
class Row,
class Col,
class AT>
35 struct hash<
fmatvec::Matrix<Type,Row,Col,AT>> {
38 for(
int r=0; r<v.rows(); ++r)
39 for(
int c=0; c<v.cols(); ++c)
40 hash_combine(h, v(r,c));
50 inline void assign(T &dst,
const T &src);
62 class InHash = boost::hash<In>,
63 class InKeyEqual = std::equal_to<In>,
64 class UnorderedMapAllocator = std::allocator<std::pair<const In, typename std::list<std::pair<const In&,Out>>::iterator>>,
65 class ListAllocator = std::allocator<std::pair<const In&, Out>> >
69 LRUCache(
size_t size_,
size_t smallSize=45,
double bucketSizeFactor = 1.5);
78 inline std::pair<Out&, bool>
operator()(
const In &in);
79 double getCacheHitRate()
const;
81 void setName(
const std::string &name_) { name = name_; }
83 std::list<std::pair<const In&,Out>, ListAllocator> itemList;
84 std::unordered_map<In,
decltype(itemList.begin()), InHash, InKeyEqual, UnorderedMapAllocator> itemMap;
86 size_t allCalls { 0 }, cacheHits { 0 };
89 bool useSmallSizeCode;
91 std::vector<size_t> timeCache;
92 std::vector<In> inCache;
93 std::vector<Out> outCache;
96 template<
class In,
class Out,
class InHash,
class InKeyEqual,
class UnorderedMapAllocator,
class ListAllocator>
99 static auto envSize =
static_cast<size_t>(-1);
100 if(envSize ==
static_cast<size_t>(-1)) {
101 const char *env = getenv(
"FMATVEC_LRUCACHE_SIZE");
111 useSmallSizeCode = size<=smallSize;
112 if(useSmallSizeCode) {
113 timeCache.resize(size);
114 inCache.resize(size);
115 outCache.resize(size);
116 for(
size_t i=0; i<size; ++i)
120 itemMap.rehash(floor(bucketSizeFactor*size));
123 template<
class In,
class Out,
class InHash,
class InKeyEqual,
class UnorderedMapAllocator,
class ListAllocator>
126 Atom::msgStatic(Atom::Debug)<<
"Cache hit rate of '"<<name<<
"' = "<<getCacheHitRate()*100<<
"%"<<std::endl;
129 template<
class In,
class Out,
class InHash,
class InKeyEqual,
class UnorderedMapAllocator,
class ListAllocator>
132 if(useSmallSizeCode) {
134 size_t minTime = std::numeric_limits<size_t>::max();
135 size_t minTimeIdx = 0;
137#ifdef FMATVEC_LRUCACHE_SMALLSIZE_WORSTPERFORMANCE
140 for(i=0; i<size && i<allCalls-1; ++i) {
141 if(timeCache[i] < minTime) {
142 minTime = timeCache[i];
147#ifdef FMATVEC_LRUCACHE_SMALLSIZE_WORSTPERFORMANCE
154#ifdef FMATVEC_LRUCACHE_SMALLSIZE_WORSTPERFORMANCE
159 timeCache[i]=allCalls;
160 return {outCache[i],
false};
163 assign(inCache[minTimeIdx], in);
164 assign(outCache[minTimeIdx], Out());
165 timeCache[minTimeIdx] = allCalls;
166 return {outCache[minTimeIdx],
true};
170 auto [it, created] = itemMap.emplace(in, itemList.begin());
174 itemList.emplace_front(it->first, Out());
176 if(itemMap.size() > size) {
177 auto itLast = --itemList.end();
178 itemMap.erase(itLast->first);
185 itemList.emplace_front(it->first, std::move(it->second->second));
186 itemList.erase(it->second);
188 it->second = itemList.begin();
189 return {it->second->second,created};
193 template<
class In,
class Out,
class InHash,
class InKeyEqual,
class UnorderedMapAllocator,
class ListAllocator>
195 return allCalls==0 ? -1 :
static_cast<double>(cacheHits)/allCalls;
199 void assign(T &dst,
const T &src) {
203 template<
class Row,
class AT>
204 void assign(Vector<Row,AT> &dst,
const Vector<Row,AT> &src) {
208 template<
class Row,
class AT>
209 void assign(RowVector<Row,AT> &dst,
const RowVector<Row,AT> &src) {
213 template<
class Type,
class Row,
class Col,
class AT>
214 void assign(Matrix<Type,Row,Col,AT> &dst,
const Matrix<Type,Row,Col,AT> &src) {
static bool msgActStatic(MsgType type)
Definition: atom.h:161
static osyncstream msgStatic(MsgType type)
Definition: atom.h:156
Definition: lrucache.h:66
std::pair< Out &, bool > operator()(const In &in)
Definition: lrucache.h:130
~LRUCache()
Prints the cache hit rate in debug builds to the stream Atom::Debug.
Definition: lrucache.h:124
LRUCache(size_t size_, size_t smallSize=45, double bucketSizeFactor=1.5)
Create a LRU cache of at most size items.
Definition: lrucache.h:97
This is the basic matrix class for arbitrary matrices.
Definition: matrix.h:52
Namespace fmatvec.
Definition: _memory.cc:28