In this example, two threads share the work as follows: the first thread processes all the even entries numbers and the second thread all the odd entry numbers. The second thread works twice as slow as the first one.
As a result, the threads need the same clusters and pages but at different points in time. With the naive way of using the reader, this read pattern will result in cache thrashing.
Using the "active entry token" API, on the other hand, the reader will be informed about which entries need to be kept in the caches and cache thrashing is prevented.
#include <array>
#include <atomic>
#include <chrono>
#include <exception>
#include <functional>
#include <iostream>
#include <mutex>
#include <thread>
#include <vector>
using namespace std::chrono_literals;
float fX;
float fY;
};
};
{
case EReadMode::kNaive: os << "naive"; break;
case EReadMode::kInformed: os << "informed"; break;
default: os << "???";
}
return os;
}
{
auto token =
reader.CreateActiveEntryToken();
{
std::lock_guard<std::mutex> guard(
gLock);
case EReadMode::kInformed: token.SetEntryNumber(i); break;
case EReadMode::kNaive: break;
default: std::terminate();
}
}
reader.GetMetrics().GetCounter(
"RNTupleReader.RPageSourceFile.nClusterLoaded")->GetValueAsInt();
reader.GetMetrics().GetCounter(
"RNTupleReader.RPageSourceFile.nPageUnsealed")->GetValueAsInt();
reader.GetMetrics().GetCounter(
"RNTupleReader.RPageSourceFile.RClusterPool.nCluster")->GetValueAsInt();
reader.GetMetrics().GetCounter(
"RNTupleReader.RPageSourceFile.RPagePool.nPage")->GetValueAsInt();
}
}
{
const auto N =
reader->GetNEntries();
std::array<std::thread, 2>
threads;
t.join();
}
std::cout <<
"Reading in mode '" <<
readMode <<
"':" << std::endl;
std::cout << "===========================" << std::endl;
reader->GetMetrics().Print(std::cout);
std::cout << "===========================" << std::endl << std::endl;
}
void Write()
{
for (int i = 0; i < 1000; ++i) {
if (i % 100 == 0)
auto prng = std::make_unique<TRandom3>();
}
}
{
for (
unsigned int i = 0; i <
counts.size(); ++i) {
graph->SetPoint(i, i,
counts[i]);
}
graph->GetXaxis()->SetTitle("Number of processed entries");
return graph;
}
{
Write();
TCanvas *canvas =
new TCanvas(
"",
"Shared Reader Example", 200, 10, 1500, 1000);
legend->AddEntry(
graph1,
"Number of decompressed pages",
"l");
latex.DrawLatexNDC(0.5, 0.95,
"Naive Reading");
graph3->GetYaxis()->SetNdivisions(8);
graph3->GetYaxis()->SetRangeUser(-0.5, 14);
legend->AddEntry(
graph3,
"Number of currently cached pages",
"p");
legend->AddEntry(
graph4,
"Number of currently cached clusters",
"p");
latex.DrawLatexNDC(0.5, 0.95,
"Informed Reading");
graph7->GetYaxis()->SetNdivisions(8);
graph7->GetYaxis()->SetRangeUser(-0.5, 14);
}
TBuffer & operator<<(TBuffer &buf, const Tmpl *obj)
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
R__EXTERN TStyle * gStyle
static std::unique_ptr< RNTupleModel > Create()
Reads RNTuple data from storage.
static std::unique_ptr< RNTupleReader > Open(std::string_view ntupleName, std::string_view storage, const ROOT::RNTupleReadOptions &options=ROOT::RNTupleReadOptions())
Open an RNTuple for reading.
static std::unique_ptr< RNTupleWriter > Recreate(std::unique_ptr< ROOT::RNTupleModel > model, std::string_view ntupleName, std::string_view storage, const ROOT::RNTupleWriteOptions &options=ROOT::RNTupleWriteOptions())
Creates an RNTupleWriter backed by storage, overwriting it if one with the same URI exists.
virtual void SetLineWidth(Width_t lwidth)
Set the line width.
virtual void SetMarkerStyle(Style_t mstyle=1)
Set the marker style.
TVirtualPad * cd(Int_t subpadnumber=0) override
Set current canvas & pad.
A TGraph is an object made of two arrays X and Y with npoints each.
To draw Mathematical Formula.
This class displays a legend box (TPaveText) containing several legend entries.
void Divide(Int_t nx=1, Int_t ny=1, Float_t xmargin=0.01, Float_t ymargin=0.01, Int_t color=0) override
Automatic pad generation by division.
void SetOptStat(Int_t stat=1)
The type of information printed in the histogram statistics box can be selected via the parameter mod...
void EnableImplicitMT(UInt_t numthreads=0)
Enable ROOT's implicit multi-threading for all objects and methods that provide an internal paralleli...