131 std::cout <<
"Thread pool size:\t\t" <<
r.fThreadPoolSize <<
'\n';
133 if (
r.fMTSetupRealTime > 0.) {
134 std::cout <<
"Real time to setup MT run:\t" <<
r.fMTSetupRealTime <<
" s\n";
135 std::cout <<
"CPU time to setup MT run:\t" <<
r.fMTSetupCpuTime <<
" s\n";
138 std::cout <<
"Real time:\t\t\t" <<
r.fRealTime <<
" s\n";
139 std::cout <<
"CPU time:\t\t\t" <<
r.fCpuTime <<
" s\n";
141 std::cout <<
"Uncompressed data read:\t\t" <<
r.fUncompressedBytesRead <<
" bytes\n";
142 std::cout <<
"Compressed data read:\t\t" <<
r.fCompressedBytesRead <<
" bytes\n";
144 const unsigned int effectiveThreads = std::max(
r.fThreadPoolSize, 1u);
146 std::cout <<
"Uncompressed throughput:\t" <<
r.fUncompressedBytesRead /
r.fRealTime / 1024 / 1024 <<
" MB/s\n";
147 std::cout <<
"\t\t\t\t" <<
r.fUncompressedBytesRead /
r.fRealTime / 1024 / 1024 / effectiveThreads
148 <<
" MB/s/thread for " << effectiveThreads <<
" threads\n";
149 std::cout <<
"Compressed throughput:\t\t" <<
r.fCompressedBytesRead /
r.fRealTime / 1024 / 1024 <<
" MB/s\n";
150 std::cout <<
"\t\t\t\t" <<
r.fCompressedBytesRead /
r.fRealTime / 1024 / 1024 / effectiveThreads
151 <<
" MB/s/thread for " << effectiveThreads <<
" threads\n\n";
153 const float cpuEfficiency = (
r.fCpuTime / effectiveThreads) /
r.fRealTime;
155 std::cout <<
"CPU Efficiency: \t\t" << (cpuEfficiency * 100) <<
"%\n";
156 std::cout <<
"Reading data is ";
157 if (cpuEfficiency > 0.80f) {
158 std::cout <<
"likely CPU bound (decompression).\n";
159 }
else if (cpuEfficiency < 0.50f) {
160 std::cout <<
"likely I/O bound.\n";
162 std::cout <<
"likely balanced (more threads may help though).\n";
164 std::cout <<
"For details run with the --help command.\n";
170 const auto argsProvided = args.size() >= 2;
171 const auto helpUsed = argsProvided && (args[1] ==
"--help" || args[1] ==
"-h");
172 const auto longHelpUsed = argsProvided && args[1] ==
"--help";
174 if (!argsProvided || helpUsed) {
180 std::cout << std::endl;
186 unsigned int nThreads = 0;
188 enum class EArgState {
kNone, kTrees, kFiles, kBranches, kThreads, kTasksPerWorkerHint } argState = EArgState::kNone;
189 enum class EBranchState {
kNone, kRegular, kRegex, kAll } branchState = EBranchState::kNone;
190 const auto branchOptionsErrMsg =
191 "Options --all-branches, --branches, and --branches-regex are mutually exclusive. You can use only one.\n";
193 for (
size_t i = 1; i < args.size(); ++i) {
194 const auto &arg = args[i];
196 if (arg ==
"--trees") {
197 argState = EArgState::kTrees;
198 }
else if (arg ==
"--files") {
199 argState = EArgState::kFiles;
200 }
else if (arg ==
"--all-branches") {
201 argState = EArgState::kNone;
202 if (branchState != EBranchState::kNone && branchState != EBranchState::kAll) {
203 std::cerr << branchOptionsErrMsg;
206 branchState = EBranchState::kAll;
208 d.fBranchNames = {
".*"};
209 }
else if (arg ==
"--branches") {
210 argState = EArgState::kBranches;
211 if (branchState != EBranchState::kNone && branchState != EBranchState::kRegular) {
212 std::cerr << branchOptionsErrMsg;
215 branchState = EBranchState::kRegular;
216 }
else if (arg ==
"--branches-regex") {
217 argState = EArgState::kBranches;
218 if (branchState != EBranchState::kNone && branchState != EBranchState::kRegex) {
219 std::cerr << branchOptionsErrMsg;
222 branchState = EBranchState::kRegex;
224 }
else if (arg ==
"--threads") {
225 argState = EArgState::kThreads;
226 }
else if (arg ==
"--tasks-per-worker") {
227 argState = EArgState::kTasksPerWorkerHint;
228 }
else if (arg[0] ==
'-') {
229 std::cerr <<
"Unrecognized option '" << arg <<
"'\n";
233 case EArgState::kTrees:
d.fTreeNames.emplace_back(arg);
break;
234 case EArgState::kFiles:
d.fFileNames.emplace_back(arg);
break;
235 case EArgState::kBranches:
d.fBranchNames.emplace_back(arg);
break;
236 case EArgState::kThreads:
237 nThreads = std::stoi(arg);
238 argState = EArgState::kNone;
240 case EArgState::kTasksPerWorkerHint:
243 argState = EArgState::kNone;
245 std::cerr <<
"ROOT was built without implicit multi-threading (IMT) support. The --tasks-per-worker option "
246 "will be ignored.\n";
249 default: std::cerr <<
"Unrecognized option '" << arg <<
"'\n";
return {};
254 return Args{std::move(
d), nThreads, branchState == EBranchState::kAll,
true};