Introduce partitioned unordered maps:

This commit implements partitioned unordered maps and makes it possible
to traverse such a map in parallel, allowing for more efficient use of
CPU resources.

The `CachedSLEs`, `TaggedCache`, and `KeyCache` classes make use of the
new functionality, which should improve performance.
This commit is contained in:
Mark Travis
2021-09-17 15:48:33 -07:00
committed by seelabs
parent 7edfbbd8bd
commit 19018e8959
26 changed files with 1089 additions and 770 deletions

View File

@@ -218,39 +218,47 @@ LedgerReplayer::gotReplayDelta(
void
LedgerReplayer::sweep()
{
std::lock_guard<std::mutex> lock(mtx_);
JLOG(j_.debug()) << "Sweeping, LedgerReplayer has " << tasks_.size()
<< " tasks, " << skipLists_.size() << " skipLists, and "
<< deltas_.size() << " deltas.";
auto const start = std::chrono::steady_clock::now();
{
std::lock_guard<std::mutex> lock(mtx_);
JLOG(j_.debug()) << "Sweeping, LedgerReplayer has " << tasks_.size()
<< " tasks, " << skipLists_.size()
<< " skipLists, and " << deltas_.size() << " deltas.";
tasks_.erase(
std::remove_if(
tasks_.begin(),
tasks_.end(),
[this](auto const& t) -> bool {
if (t->finished())
{
JLOG(j_.debug())
<< "Sweep task " << t->getTaskParameter().finishHash_;
return true;
}
return false;
}),
tasks_.end());
tasks_.erase(
std::remove_if(
tasks_.begin(),
tasks_.end(),
[this](auto const& t) -> bool {
if (t->finished())
{
JLOG(j_.debug()) << "Sweep task "
<< t->getTaskParameter().finishHash_;
return true;
}
return false;
}),
tasks_.end());
auto removeCannotLocked = [](auto& subTasks) {
for (auto it = subTasks.begin(); it != subTasks.end();)
{
if (auto item = it->second.lock(); !item)
auto removeCannotLocked = [](auto& subTasks) {
for (auto it = subTasks.begin(); it != subTasks.end();)
{
it = subTasks.erase(it);
if (auto item = it->second.lock(); !item)
{
it = subTasks.erase(it);
}
else
++it;
}
else
++it;
}
};
removeCannotLocked(skipLists_);
removeCannotLocked(deltas_);
};
removeCannotLocked(skipLists_);
removeCannotLocked(deltas_);
}
JLOG(j_.debug()) << " LedgerReplayer sweep lock duration "
<< std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now() - start)
.count()
<< "ms";
}
void