mirror of
https://github.com/ceph/ceph
synced 2025-01-31 07:22:56 +00:00
Merge pull request #5257 from t-miyamae/wip-mshec-fixlogic4
erasure code: shec performance optimization by decoding cache Reviewed-by: Loic Dachary <ldachary@redhat.com>
This commit is contained in:
commit
49ee455b35
@ -562,6 +562,14 @@ int ErasureCodeShec::shec_make_decoding_matrix(bool prepare, int *want_, int *av
|
||||
}
|
||||
}
|
||||
|
||||
if (tcache.getDecodingTableFromCache(decoding_matrix,
|
||||
dm_row, dm_column, minimum,
|
||||
technique,
|
||||
k, m, c, w,
|
||||
want, avails)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (unsigned long long pp = 0; pp < (1ull << m); ++pp) {
|
||||
|
||||
// select parity chunks
|
||||
@ -755,6 +763,9 @@ int ErasureCodeShec::shec_make_decoding_matrix(bool prepare, int *want_, int *av
|
||||
|
||||
int ret = jerasure_invert_matrix(tmpmat, decoding_matrix, mindup, w);
|
||||
|
||||
tcache.putDecodingTableToCache(decoding_matrix, dm_row, dm_column, minimum, technique,
|
||||
k, m, c, w, want, avails);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -23,34 +23,95 @@
|
||||
#include "common/debug.h"
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
#define dout_subsys ceph_subsys_osd
|
||||
#undef dout_prefix
|
||||
#define dout_prefix _tc_prefix(_dout)
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
static ostream&
|
||||
_tc_prefix(std::ostream* _dout) {
|
||||
return *_dout << "ErasureCodeShecTableCache: ";
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
ErasureCodeShecTableCache::~ErasureCodeShecTableCache()
|
||||
{
|
||||
Mutex::Locker lock(codec_tables_guard);
|
||||
|
||||
codec_technique_tables_t::const_iterator ttables_it;
|
||||
codec_tables_t::const_iterator tables_it;
|
||||
codec_tables_t_::const_iterator tables_it_;
|
||||
codec_tables_t__::const_iterator tables_it__;
|
||||
codec_table_t::const_iterator table_it;
|
||||
|
||||
// clean-up all allocated tables
|
||||
{
|
||||
codec_technique_tables_t::const_iterator ttables_it;
|
||||
codec_tables_t::const_iterator tables_it;
|
||||
codec_tables_t_::const_iterator tables_it_;
|
||||
codec_tables_t__::const_iterator tables_it__;
|
||||
codec_table_t::const_iterator table_it;
|
||||
|
||||
for (ttables_it = encoding_table.begin(); ttables_it != encoding_table.end(); ++ttables_it) {
|
||||
for (tables_it = ttables_it->second.begin(); tables_it != ttables_it->second.end(); ++tables_it) {
|
||||
for (tables_it_ = tables_it->second.begin(); tables_it_ != tables_it->second.end(); ++tables_it_) {
|
||||
for (tables_it__ = tables_it_->second.begin(); tables_it__ != tables_it_->second.end(); ++tables_it__) {
|
||||
for (table_it = tables_it__->second.begin(); table_it != tables_it__->second.end(); ++table_it) {
|
||||
if (table_it->second) {
|
||||
if (*(table_it->second)) {
|
||||
delete *(table_it->second);
|
||||
}
|
||||
delete table_it->second;
|
||||
}
|
||||
}
|
||||
for (ttables_it = encoding_table.begin(); ttables_it != encoding_table.end(); ++ttables_it) {
|
||||
for (tables_it = ttables_it->second.begin(); tables_it != ttables_it->second.end(); ++tables_it) {
|
||||
for (tables_it_ = tables_it->second.begin(); tables_it_ != tables_it->second.end(); ++tables_it_) {
|
||||
for (tables_it__ = tables_it_->second.begin(); tables_it__ != tables_it_->second.end(); ++tables_it__) {
|
||||
for (table_it = tables_it__->second.begin(); table_it != tables_it__->second.end(); ++table_it) {
|
||||
if (table_it->second) {
|
||||
if (*(table_it->second)) {
|
||||
delete *(table_it->second);
|
||||
}
|
||||
delete table_it->second;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
std::map<int, lru_map_t*>::const_iterator lru_map_it;
|
||||
std::map<int, lru_list_t*>::const_iterator lru_list_it;
|
||||
|
||||
for (lru_map_it = decoding_tables.begin();
|
||||
lru_map_it != decoding_tables.end();
|
||||
++lru_map_it) {
|
||||
if (lru_map_it->second) {
|
||||
delete lru_map_it->second;
|
||||
}
|
||||
}
|
||||
|
||||
for (lru_list_it = decoding_tables_lru.begin();
|
||||
lru_list_it != decoding_tables_lru.end();
|
||||
++lru_list_it) {
|
||||
if (lru_list_it->second) {
|
||||
delete lru_list_it->second;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ErasureCodeShecTableCache::lru_map_t*
|
||||
ErasureCodeShecTableCache::getDecodingTables(int technique) {
|
||||
// the caller must hold the guard mutex:
|
||||
// => Mutex::Locker lock(codec_tables_guard);
|
||||
|
||||
// create an lru_map if not yet allocated
|
||||
if (!decoding_tables[technique]) {
|
||||
decoding_tables[technique] = new lru_map_t;
|
||||
}
|
||||
return decoding_tables[technique];
|
||||
}
|
||||
|
||||
ErasureCodeShecTableCache::lru_list_t*
|
||||
ErasureCodeShecTableCache::getDecodingTablesLru(int technique) {
|
||||
// the caller must hold the guard mutex:
|
||||
// => Mutex::Locker lock(codec_tables_guard);
|
||||
|
||||
// create an lru_list if not yet allocated
|
||||
if (!decoding_tables_lru[technique]) {
|
||||
decoding_tables_lru[technique] = new lru_list_t;
|
||||
}
|
||||
return decoding_tables_lru[technique];
|
||||
}
|
||||
|
||||
int**
|
||||
@ -95,3 +156,162 @@ ErasureCodeShecTableCache::getLock()
|
||||
{
|
||||
return &codec_tables_guard;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
ErasureCodeShecTableCache::getDecodingCacheSignature(int k, int m, int c, int w,
|
||||
int *erased, int *avails) {
|
||||
uint64_t signature = 0;
|
||||
signature = (uint64_t)k;
|
||||
signature |= ((uint64_t)m << 6);
|
||||
signature |= ((uint64_t)c << 12);
|
||||
signature |= ((uint64_t)w << 18);
|
||||
|
||||
for (int i=0; i < k+m; i++) {
|
||||
signature |= ((uint64_t)(avails[i] ? 1 : 0) << (24+i));
|
||||
}
|
||||
for (int i=0; i < k+m; i++) {
|
||||
signature |= ((uint64_t)(erased[i] ? 1 : 0) << (44+i));
|
||||
}
|
||||
return signature;
|
||||
}
|
||||
|
||||
bool
|
||||
ErasureCodeShecTableCache::getDecodingTableFromCache(int* decoding_matrix,
|
||||
int* dm_row,
|
||||
int* dm_column,
|
||||
int* minimum,
|
||||
int technique,
|
||||
int k,
|
||||
int m,
|
||||
int c,
|
||||
int w,
|
||||
int* erased,
|
||||
int* avails) {
|
||||
// --------------------------------------------------------------------------
|
||||
// LRU decoding matrix cache
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
uint64_t signature = getDecodingCacheSignature(k, m, c, w, erased, avails);
|
||||
Mutex::Locker lock(codec_tables_guard);
|
||||
|
||||
dout(20) << "[ get table ] = " << signature << dendl;
|
||||
|
||||
// we try to fetch a decoding table from an LRU cache
|
||||
lru_map_t* decode_tbls_map =
|
||||
getDecodingTables(technique);
|
||||
|
||||
lru_list_t* decode_tbls_lru =
|
||||
getDecodingTablesLru(technique);
|
||||
|
||||
lru_map_t::iterator decode_tbls_map_it = decode_tbls_map->find(signature);
|
||||
if (decode_tbls_map_it == decode_tbls_map->end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
dout(20) << "[ cached table ] = " << signature << dendl;
|
||||
// copy parameters out of the cache
|
||||
|
||||
memcpy(decoding_matrix,
|
||||
decode_tbls_map_it->second.second.decoding_matrix,
|
||||
k * k * sizeof(int));
|
||||
memcpy(dm_row,
|
||||
decode_tbls_map_it->second.second.dm_row,
|
||||
k * sizeof(int));
|
||||
memcpy(dm_column,
|
||||
decode_tbls_map_it->second.second.dm_column,
|
||||
k * sizeof(int));
|
||||
memcpy(minimum,
|
||||
decode_tbls_map_it->second.second.minimum,
|
||||
(k+m) * sizeof(int));
|
||||
|
||||
// find item in LRU queue and push back
|
||||
decode_tbls_lru->splice(decode_tbls_lru->end(),
|
||||
*decode_tbls_lru,
|
||||
decode_tbls_map_it->second.first);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ErasureCodeShecTableCache::putDecodingTableToCache(int* decoding_matrix,
|
||||
int* dm_row,
|
||||
int* dm_column,
|
||||
int* minimum,
|
||||
int technique,
|
||||
int k,
|
||||
int m,
|
||||
int c,
|
||||
int w,
|
||||
int* erased,
|
||||
int* avails) {
|
||||
// --------------------------------------------------------------------------
|
||||
// LRU decoding matrix cache
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
Mutex::Locker lock(codec_tables_guard);
|
||||
|
||||
uint64_t signature = getDecodingCacheSignature(k, m, c, w, erased, avails);
|
||||
dout(20) << "[ put table ] = " << signature << dendl;
|
||||
|
||||
// we store a new table to the cache
|
||||
|
||||
// bufferptr cachetable;
|
||||
|
||||
lru_map_t* decode_tbls_map =
|
||||
getDecodingTables(technique);
|
||||
|
||||
lru_list_t* decode_tbls_lru =
|
||||
getDecodingTablesLru(technique);
|
||||
|
||||
if (decode_tbls_map->count(signature)) {
|
||||
dout(20) << "[ already on table ] = " << signature << dendl;
|
||||
|
||||
// find item in LRU queue and push back
|
||||
decode_tbls_lru->splice(decode_tbls_lru->end(),
|
||||
*decode_tbls_lru,
|
||||
(*decode_tbls_map)[signature].first);
|
||||
return;
|
||||
}
|
||||
|
||||
// evt. shrink the LRU queue/map
|
||||
if ((int)decode_tbls_lru->size() >=
|
||||
ErasureCodeShecTableCache::decoding_tables_lru_length) {
|
||||
dout(20) << "[ shrink lru ] = " << signature << dendl;
|
||||
// remove from map
|
||||
decode_tbls_map->erase(decode_tbls_lru->front());
|
||||
// remove from lru
|
||||
decode_tbls_lru->pop_front();
|
||||
}
|
||||
|
||||
{
|
||||
dout(20) << "[ store table ] = " << signature << dendl;
|
||||
|
||||
decode_tbls_lru->push_back(signature);
|
||||
|
||||
// allocate a new buffer
|
||||
lru_list_t::iterator it_end = decode_tbls_lru->end();
|
||||
it_end--;
|
||||
|
||||
lru_entry_t &map_value =
|
||||
(*decode_tbls_map)[signature] =
|
||||
std::make_pair(it_end, DecodingCacheParameter());
|
||||
map_value.second.decoding_matrix = new int[k*k];
|
||||
map_value.second.dm_row = new int[k];
|
||||
map_value.second.dm_column = new int[k];
|
||||
map_value.second.minimum = new int[k+m];
|
||||
|
||||
memcpy(map_value.second.decoding_matrix,
|
||||
decoding_matrix,
|
||||
k * k * sizeof(int));
|
||||
memcpy(map_value.second.dm_row,
|
||||
dm_row,
|
||||
k * sizeof(int));
|
||||
memcpy(map_value.second.dm_column,
|
||||
dm_column,
|
||||
k * sizeof(int));
|
||||
memcpy(map_value.second.minimum,
|
||||
minimum,
|
||||
(k+m) * sizeof(int));
|
||||
|
||||
dout(20) << "[ cache size ] = " << decode_tbls_lru->size() << dendl;
|
||||
}
|
||||
}
|
||||
|
@ -31,11 +31,43 @@ class ErasureCodeShecTableCache {
|
||||
// ---------------------------------------------------------------------------
|
||||
// This class implements a table cache for encoding and decoding matrices.
|
||||
// Encoding matrices are shared for the same (k,m,c,w) combination.
|
||||
// It supplies a decoding matrix lru cache which is shared for identical
|
||||
// matrix types e.g. there is one cache (lru-list + lru-map)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
class DecodingCacheParameter {
|
||||
public:
|
||||
int* decoding_matrix; // size: k*k
|
||||
int* dm_row; // size: k
|
||||
int* dm_column; // size: k
|
||||
int* minimum; // size: k+m
|
||||
DecodingCacheParameter() {
|
||||
decoding_matrix = 0;
|
||||
dm_row = 0;
|
||||
dm_column = 0;
|
||||
minimum = 0;
|
||||
}
|
||||
~DecodingCacheParameter() {
|
||||
if (decoding_matrix) {
|
||||
delete[] decoding_matrix;
|
||||
}
|
||||
if (dm_row) {
|
||||
delete[] dm_row;
|
||||
}
|
||||
if (dm_column) {
|
||||
delete[] dm_column;
|
||||
}
|
||||
if (minimum) {
|
||||
delete[] minimum;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
typedef std::pair<std::list<std::string>::iterator, bufferptr> lru_entry_t;
|
||||
static const int decoding_tables_lru_length = 10000;
|
||||
typedef std::pair<std::list<uint64_t>::iterator,
|
||||
DecodingCacheParameter> lru_entry_t;
|
||||
typedef std::map< int, int** > codec_table_t;
|
||||
typedef std::map< int, codec_table_t > codec_tables_t__;
|
||||
typedef std::map< int, codec_tables_t__ > codec_tables_t_;
|
||||
@ -43,6 +75,9 @@ class ErasureCodeShecTableCache {
|
||||
typedef std::map< int, codec_tables_t > codec_technique_tables_t;
|
||||
// int** matrix = codec_technique_tables_t[technique][k][m][c][w]
|
||||
|
||||
typedef std::map< uint64_t, lru_entry_t > lru_map_t;
|
||||
typedef std::list< uint64_t > lru_list_t;
|
||||
|
||||
ErasureCodeShecTableCache() :
|
||||
codec_tables_guard("shec-lru-cache")
|
||||
{
|
||||
@ -52,15 +87,38 @@ class ErasureCodeShecTableCache {
|
||||
|
||||
Mutex codec_tables_guard; // mutex used to protect modifications in encoding/decoding table maps
|
||||
|
||||
bool getDecodingTableFromCache(int* matrix,
|
||||
int* dm_row, int* dm_column,
|
||||
int* minimum,
|
||||
int technique,
|
||||
int k, int m, int c, int w,
|
||||
int* want, int* avails);
|
||||
|
||||
void putDecodingTableToCache(int* matrix,
|
||||
int* dm_row, int* dm_column,
|
||||
int* minimum,
|
||||
int technique,
|
||||
int k, int m, int c, int w,
|
||||
int* want, int* avails);
|
||||
|
||||
int** getEncodingTable(int technique, int k, int m, int c, int w);
|
||||
int** getEncodingTableNoLock(int technique, int k, int m, int c, int w);
|
||||
int* setEncodingTable(int technique, int k, int m, int c, int w, int*);
|
||||
|
||||
private:
|
||||
codec_technique_tables_t encoding_table; // encoding coefficients accessed via table[technique][k][m]
|
||||
|
||||
// encoding table accessed via table[matrix][k][m][c][w]
|
||||
// decoding table cache accessed via map[matrixtype]
|
||||
// decoding table lru list accessed via list[matrixtype]
|
||||
codec_technique_tables_t encoding_table;
|
||||
std::map<int, lru_map_t*> decoding_tables;
|
||||
std::map<int, lru_list_t*> decoding_tables_lru;
|
||||
|
||||
lru_map_t* getDecodingTables(int technique);
|
||||
lru_list_t* getDecodingTablesLru(int technique);
|
||||
uint64_t getDecodingCacheSignature(int k, int m, int c, int w,
|
||||
int *want, int *avails);
|
||||
|
||||
Mutex* getLock();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user