| 284 | } |
| 285 | |
| 286 | void |
| 287 | bench( |
| 288 | string_view verb, |
| 289 | file_list const& vf, |
| 290 | impl_list const& vi, std::size_t Trials) |
| 291 | { |
| 292 | std::vector<sample> trial; |
| 293 | for(unsigned i = 0; i < vf.size(); ++i) |
| 294 | { |
| 295 | for(unsigned j = 0; j < vi.size(); ++j) |
| 296 | { |
| 297 | trial.clear(); |
| 298 | std::size_t repeat = 1; |
| 299 | |
| 300 | auto const f = [&]{ |
| 301 | return vi[j].get()->bench(verb, vf[i], repeat); |
| 302 | }; |
| 303 | |
| 304 | // helps with the caching, which reduces noise; also, we determine |
| 305 | // if this configuration should be skipped altogether |
| 306 | auto const elapsed = f(); |
| 307 | if( elapsed == std::chrono::milliseconds::zero() ) |
| 308 | { |
| 309 | print_prefix(dout, vf[i], *vi[j], verb) |
| 310 | << "," << "N/A" |
| 311 | << "," << "N/A" |
| 312 | << "," << "N/A" |
| 313 | << "\n"; |
| 314 | print_prefix(strout, vf[i], *vi[j], verb) |
| 315 | << "," << "N/A" << "\n"; |
| 316 | continue; |
| 317 | } |
| 318 | |
| 319 | repeat = 1000; |
| 320 | for(unsigned k = 0; k < Trials; ++k) |
| 321 | { |
| 322 | auto result = run_for(std::chrono::seconds(5), f); |
| 323 | result.calls *= repeat; |
| 324 | result.mbs = megabytes_per_second( |
| 325 | vf[i], result.calls, result.millis); |
| 326 | print_prefix(dout, vf[i], *vi[j], verb) |
| 327 | << "," << result.calls |
| 328 | << "," << result.millis |
| 329 | << "," << result.mbs |
| 330 | << "\n"; |
| 331 | trial.push_back(result); |
| 332 | // adjust repeat to avoid overlong tests |
| 333 | repeat = 250 * result.calls / result.millis; |
| 334 | } |
| 335 | |
| 336 | // clean up the samples |
| 337 | std::sort( |
| 338 | trial.begin(), |
| 339 | trial.end(), |
| 340 | [](sample const& lhs, sample const& rhs) |
| 341 | { |
| 342 | return lhs.mbs < rhs.mbs; |
| 343 | }); |